is not a file.
+IMAGES/FIT16.GIF=images/Fit16.gif
diff --git a/src/main/resources/i18n_ja_JP.properties b/src/main/resources/i18n_ja_JP.properties
new file mode 100644
index 0000000..cebd4e8
--- /dev/null
+++ b/src/main/resources/i18n_ja_JP.properties
@@ -0,0 +1,69 @@
+dialog.quit=\u7d42\u4e86
+dialog.cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
+dialog.msg1=\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u7d42\u4e86\u3057\u307e\u3059\u3002
+dialog.select=\u9078\u629e
+
+menu.tools=\u30c4\u30fc\u30eb
+menu.restamp=Restamp
+button.close=\u9589\u3058\u308b
+
+menu.quit=\u7d42\u4e86...
+button.next=\u6b21\u3078
+button.previous=\u623b\u308b
+button.execute=\u51e6\u7406\u5b9f\u884c
+button.select=\u9078\u629e...
+button.update=\u5909\u66f4...
+button.reset=\u518d\u8a2d\u5b9a...
+
+tab.100=1. \u753b\u50cf\u5143\u306e\u30d5\u30a1\u30a4\u30eb\u30d5\u30a9\u30eb\u30c0
+label.100=1. \u4f4d\u7f6e\u60c5\u5831\u3092\u4ed8\u52a0\u3057\u305f\u3044\u753b\u50cf\u30d5\u30a1\u30a4\u30eb\u304c\u683c\u7d0d\u3055\u308c\u3066\u3044\u308b\u30d5\u30a9\u30eb\u30c0\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002
- \u30b3\u30d4\u30fc\u52d5\u4f5c\u3092\u884c\u3046\u3068\u3001\u30d5\u30a1\u30a4\u30eb\u66f4\u65b0\u6642\u523b\u304c\u30b3\u30d4\u30fc\u3092\u5b9f\u884c\u3057\u305f\u6642\u523b\u306b\u66f8\u304d\u63db\u308f\u3063\u3066\u3057\u307e\u3046\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002\u30ab\u30e1\u30e9SD\u30ab\u30fc\u30c9\u5185\u306e\u30d5\u30a9\u30eb\u30c0\u3092\u76f4\u63a5\u6307\u5b9a\u3059\u308b\u3053\u3068\u3092\u304a\u3059\u3059\u3081\u3057\u307e\u3059\u3002
+label.110=\u5bfe\u8c61\u30d5\u30a9\u30eb\u30c0
+
+tab.200=2. \u57fa\u6e96\u3068\u3059\u308b\u753b\u50cf\u306e\u9078\u629e
+tab.restamp.200=2. \u57fa\u6e96\u3068\u3059\u308b\u753b\u50cf(\u958b\u59cb\u753b\u50cf)\u306e\u9078\u629e
+tab.restamp.250=3. \u57fa\u6e96\u3068\u3059\u308b\u753b\u50cf(\u7d42\u4e86\u753b\u50cf)\u306e\u9078\u629e
+label.200=2. \u6b63\u78ba\u306a\u64ae\u5f71\u6642\u523b\u304c\u5224\u660e\u3067\u304d\u308b\u753b\u50cf\u3092\u9078\u3093\u3067\u304f\u3060\u3055\u3044\u3002
- \u30b9\u30de\u30fc\u30c8\u30d5\u30a9\u30f3\u306e\u6642\u8a08\u753b\u9762\uff08\u79d2\u304c\u5224\u5225\u3067\u304d\u308b\u3053\u3068\uff09\u3092\u64ae\u5f71\u3057\u305f\u753b\u50cf
- \u30ab\u30e1\u30e9\u306e\u6642\u8a08\u304c\u6b63\u78ba\u306a\u3089\u3070\u3001\u3069\u306e\u753b\u50cf\u3092\u9078\u3093\u3067\u3082\u69cb\u3044\u307e\u305b\u3093\u3002
+label.210=\u57fa\u6e96\u6642\u523b\u753b\u50cf
+label.220=EXIF\u306e\u65e5\u6642\u3092\u57fa\u6e96\u306b\u3059\u308b
+label.230=\u30d5\u30a1\u30a4\u30eb\u66f4\u65b0\u65e5\u6642\u3092\u57fa\u6e96\u306b\u3059\u308b
+
+tab.300=2a. \u672c\u5f53\u306e\u6642\u523b\u3092\u8a2d\u5b9a
+tab.restamp.300=2a. \u958b\u59cb\u753b\u50cf\u306e\u672c\u5f53\u306e\u6642\u523b\u3092\u8a2d\u5b9a
+tab.restamp.350=3a. \u7d42\u4e86\u753b\u50cf\u306e\u672c\u5f53\u306e\u6642\u523b\u3092\u8a2d\u5b9a
+label.300=3. \u6b63\u78ba\u306a\u64ae\u5f71\u6642\u523b\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
- \u30ab\u30e1\u30e9\u306e\u6642\u8a08\u304c\u6b63\u78ba\u306a\u3089\u3070\u3001\u8a2d\u5b9a\u3092\u5909\u66f4\u3059\u308b\u5fc5\u8981\u306f\u3042\u308a\u307e\u305b\u3093\u3002
+label.310=\u57fa\u6e96\u6642\u523b
+label.restamp.310=\u57fa\u6e96\u6642\u523b(\u958b\u59cb\u753b\u50cf)
+
+tab.400=3. GPX\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e
+label.400=4. \u30d2\u30e2\u4ed8\u3092\u884c\u3046GPX\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002
- \u30d5\u30a9\u30eb\u30c0\u3092\u6307\u5b9a\u3059\u308b\u3068\u3001\u30d5\u30a9\u30eb\u30c0\u5185\u306b\u3042\u308b\u3059\u3079\u3066\u306eGPX\u30d5\u30a1\u30a4\u30eb\u3092\u5bfe\u8c61\u3068\u3057\u307e\u3059\u3002
+label.410=GPX\u30d5\u30a9\u30eb\u30c0
+label.420=\u30bb\u30b0\u30e1\u30f3\u30c8'trkseg'\u306e\u6700\u521d\u306e\uff11\u30ce\u30fc\u30c9\u306f\u7121\u8996\u3059\u308b
+label.430=\u751f\u6210\u3055\u308c\u305fGPX\u30d5\u30a1\u30a4\u30eb\uff08\u30d5\u30a1\u30a4\u30eb\u540d\u304c'_.gpx'\u3067\u7d42\u308f\u308b\u3082\u306e\uff09\u3082\u5909\u63db\u306e\u5bfe\u8c61\u306b\u3059\u308b
+
+tab.500=4. EXIF\u5909\u63db\u306e\u5b9f\u884c
+label.500=EXIF\u5909\u63db\u3092\u884c\u3046\u304b\u3069\u3046\u304b\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044
+label.501=EXIF\u5909\u63db\u3092\u884c\u3046\u5834\u5408\u306b\u306f\u3001\u5909\u63db\u30d5\u30a1\u30a4\u30eb\u3092\u51fa\u529b\u3059\u308b\u30d5\u30a9\u30eb\u30c0\u3082\u6307\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
+label.502=\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u306b\u306f\u3001\u66f8\u304d\u8fbc\u307f\u6a29\u9650\u3068\u3001\u5341\u5206\u306a\u7a7a\u304d\u5bb9\u91cf\u304c\u5fc5\u8981\u3067\u3059\u3002
+label.510=IMG\u306e\u5909\u63db\u3092\u3059\u308b
+label.520=GPX\u30d5\u30a1\u30a4\u30eb\u6642\u9593\u5916\u306e\u30d5\u30a1\u30a4\u30eb\u3082\u30b3\u30d4\u30fc\u3059\u308b
+label.530=\u51fa\u529b\u30d5\u30a9\u30eb\u30c0
+label.540=EXIF\u306e\u5909\u63db\u3092\u3059\u308b
+label.550=\u30dd\u30a4\u30f3\u30c8\u30de\u30fc\u30ab\u30fc\u3092GPX\u30d5\u30a1\u30a4\u30eb\u306b\u51fa\u529b\u3059\u308b
+label.560=\u30bd\u30fc\u30b9GPX\u306e\u3092\u7121\u8996\u3059\u308b
+label.570=\u51fa\u529bGPX\u306b\u3092\u4e0a\u66f8\u304d\u3059\u308b
+
+tab.restamp.400=4. \u5909\u63db\u306e\u5b9f\u884c
+
+msg.100=GPX\u30d5\u30a1\u30a4\u30eb\u307e\u305f\u306f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002('%s')
+msg.110=\u5bfe\u8c61\u3068\u306a\u308bGPX\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093('%s')
+msg.120=\u8907\u6570\u306eGPX\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308b\u3068\u304d\u306b\u306f\u3001'IMG.OUTPUT_ALL'\u30aa\u30d7\u30b7\u30e7\u30f3\u306f\u6307\u5b9a\u3067\u304d\u307e\u305b\u3093\u3002
+msg.130='%s'\u306e\u66f8\u5f0f\u304c\u9055\u3044\u307e\u3059(%s)
+msg.140='%s'\u306bEXIF\u60c5\u5831\u304c\u3042\u308a\u307e\u305b\u3093
+
+msg.200=[error] \u304c\u5b58\u5728\u3057\u307e\u305b\u3093
+msg.210=[error] \u304c\u30d5\u30a9\u30eb\u30c0\u3058\u3083\u306a\u3044
+msg.220=[error] \u304c\u5b58\u5728\u3057\u307e\u305b\u3093
+msg.230=[error] \u304c\u30d5\u30a1\u30a4\u30eb\u3058\u3083\u306a\u3044
+msg.240=[error] \u304c\u5b58\u5728\u3057\u307e\u305b\u3093
+msg.250=[error] \u304c\u30d5\u30a1\u30a4\u30eb\u3058\u3083\u306a\u3044
+IMAGES/FIT16.GIF=images/Fit16.gif
diff --git a/src/test/java/osm/jp/gpx/AppParametersTest.java b/src/test/java/osm/jp/gpx/AppParametersTest.java
new file mode 100644
index 0000000..e0f9f6b
--- /dev/null
+++ b/src/test/java/osm/jp/gpx/AppParametersTest.java
@@ -0,0 +1,204 @@
+package osm.jp.gpx;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.experimental.runners.*;
+
+@RunWith(Enclosed.class)
+public class AppParametersTest {
+
+ public static class 定義ファイルが存在しない場合 {
+ AppParameters params;
+
+ @Before
+ public void setUp() throws Exception {
+ File iniFile = new File("AdjustTime.ini");
+ File orgFile = new File("AdjustTime.ini.org");
+
+ if (orgFile.exists()) {
+ orgFile.delete();
+ }
+ if (iniFile.exists()) {
+ iniFile.renameTo(orgFile);
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ File iniFile = new File("AdjustTime.ini");
+ File orgFile = new File("AdjustTime.ini.org");
+ if (iniFile.exists()) {
+ iniFile.delete();
+ }
+ if (orgFile.exists()) {
+ orgFile.renameTo(iniFile);
+ }
+ }
+
+ @Test
+ public void IMG_OUTPUT_ALLが定義されていない時() {
+ try {
+ params = new AppParameters("testdata/AdjustTime.off.ini");
+ String valueStr = params.getProperty(AppParameters.IMG_OUTPUT_ALL);
+ assertThat(valueStr, is("false"));
+ }
+ catch (IOException e) {
+ fail("Exceptionが発生した。");
+ }
+ }
+ }
+
+ public static class 定義ファイルがtureに定義されているとき {
+
+ @Before
+ public void setUp() throws Exception {
+ File iniFile = new File("AdjustTime.ini");
+ File orgFile = new File("AdjustTime.ini.org");
+ File testFile = new File("testdata", "AdjustTime.on.ini");
+
+ if (orgFile.exists()) {
+ orgFile.delete();
+ }
+ if (iniFile.exists()) {
+ iniFile.renameTo(orgFile);
+ }
+
+ FileInputStream inStream = new FileInputStream(testFile);
+ FileOutputStream outStream = new FileOutputStream(new File("AdjustTime.ini"));
+ FileChannel inChannel = inStream.getChannel();
+ FileChannel outChannel = outStream.getChannel();
+ try {
+ inChannel.transferTo(0, inChannel.size(),outChannel);
+ }
+ finally {
+ if (inChannel != null) inChannel.close();
+ if (outChannel != null) outChannel.close();
+ inStream.close();
+ outStream.close();
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ File iniFile = new File("AdjustTime.ini");
+ File orgFile = new File("AdjustTime.ini.org");
+ if (iniFile.exists()) {
+ iniFile.delete();
+ }
+ if (orgFile.exists()) {
+ orgFile.renameTo(iniFile);
+ }
+ }
+
+ @Test
+ public void IMG_OUTPUT_ALLがtureに定義されているとき() {
+ try {
+ AppParameters params;
+ params = new AppParameters();
+ String valueStr = params.getProperty(AppParameters.IMG_OUTPUT_ALL);
+ assertThat(valueStr, is("true"));
+ }
+ catch (IOException e) {
+ fail("Exceptionが発生した。");
+ }
+ }
+
+ @Test
+ public void IMG_OUTPUT_ALLをfalseに書き換える() {
+ try {
+ AppParameters params = new AppParameters();
+ params.setProperty(AppParameters.IMG_OUTPUT_ALL, "false");
+ params.store();
+ params = null;
+ AppParameters newParams = new AppParameters();
+ String valueStr = newParams.getProperty(AppParameters.IMG_OUTPUT_ALL);
+ assertThat(valueStr, is("false"));
+ }
+ catch (IOException e) {
+ fail("Exceptionが発生した。");
+ }
+ }
+ }
+
+ public static class 定義ファイルがfalseに定義されているとき {
+
+ @Before
+ public void setUp() throws Exception {
+ File iniFile = new File("AdjustTime.ini");
+ File orgFile = new File("AdjustTime.ini.org");
+ File testFile = new File("testdata", "AdjustTime.off.ini");
+
+ if (orgFile.exists()) {
+ orgFile.delete();
+ }
+ if (iniFile.exists()) {
+ iniFile.renameTo(orgFile);
+ }
+
+ FileInputStream inStream = new FileInputStream(testFile);
+ FileOutputStream outStream = new FileOutputStream(new File("AdjustTime.ini"));
+ FileChannel inChannel = inStream.getChannel();
+ FileChannel outChannel = outStream.getChannel();
+ try {
+ inChannel.transferTo(0, inChannel.size(),outChannel);
+ }
+ finally {
+ if (inChannel != null) inChannel.close();
+ if (outChannel != null) outChannel.close();
+ inStream.close();
+ outStream.close();
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ File iniFile = new File("AdjustTime.ini");
+ File orgFile = new File("AdjustTime.ini.org");
+ if (iniFile.exists()) {
+ iniFile.delete();
+ }
+ if (orgFile.exists()) {
+ orgFile.renameTo(iniFile);
+ }
+ }
+
+ @Test
+ public void IMG_OUTPUT_ALLがfalseに定義されているとき() {
+ try {
+ AppParameters params = new AppParameters();
+ String valueStr = params.getProperty(AppParameters.IMG_OUTPUT_ALL);
+ assertThat(valueStr, is("false"));
+ }
+ catch (IOException e) {
+ fail("Exceptionが発生した。");
+ }
+ }
+
+ @Test
+ public void IMG_OUTPUT_ALLをtrueに書き換える() {
+ try {
+ AppParameters params = new AppParameters();
+ params.setProperty(AppParameters.IMG_OUTPUT_ALL, "true");
+ params.store();
+ params = null;
+ AppParameters newParams = new AppParameters();
+ String valueStr = newParams.getProperty(AppParameters.IMG_OUTPUT_ALL);
+ assertThat(valueStr, is("true"));
+ }
+ catch (IOException e) {
+ fail("Exceptionが発生した。");
+ }
+ }
+ }
+}
diff --git a/src/test/java/osm/jp/gpx/ElementMapTRKPTTest.java b/src/test/java/osm/jp/gpx/ElementMapTRKPTTest.java
new file mode 100644
index 0000000..26c3be9
--- /dev/null
+++ b/src/test/java/osm/jp/gpx/ElementMapTRKPTTest.java
@@ -0,0 +1,286 @@
+package osm.jp.gpx;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.*;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.RunWith;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+@RunWith(Enclosed.class)
+public class ElementMapTRKPTTest {
+
+ public static class Keyのみ {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ ElementMapTRKPT map = null;
+ long timeL;
+ static String[] values = {
+ "1970-01-01 08:59:59.999",
+ "1970-01-01 09:00:00.000",
+ "1970-01-01 09:00:00.001",
+ "2018-10-25 07:59:59.999",
+ "2018-10-25 08:00:00.000",
+ "2018-10-25 08:00:00.001"
+ };
+
+ @Before
+ public void setUp() throws Exception {
+ timeL = (sdf.parse("2018-10-25 08:00:00.000")).getTime();
+ map = new ElementMapTRKPT();
+ map.put(new Date(timeL), null); // 5-6: 2018-10-25 08:00:00.000
+ map.put(new Date(timeL + 1L), null); // 7: 2018-10-25 08:00:00.001
+ map.put(new Date(timeL - 1L), null); // 4: 2018-10-25 07:59:59.999
+ map.put(new Date(1L), null); // 3: 1970-01-01 09:00:00.001
+ map.put(new Date(0L), null); // 2: 1970-01-01 09:00:00.000
+ map.put(new Date(-1L), null); // 1: 1970-01-01 08:59:59.999
+ map.put(new Date(timeL), null); // 5-6: 2018-10-25 08:00:00.000
+ }
+
+ @Test
+ public void 同一キーをPUTした場合() {
+ assertThat(map.size(), is(6));
+ }
+
+ @Test
+ public void イテレータを使って読みだす() {
+ assertThat(map.size(), is(6));
+
+ int i = 0;
+ for (Date key : map.keySet()) {
+ assertThat(sdf.format(key), is(values[i++]));
+ }
+ }
+
+ @Test
+ public void 拡張FOR文を使って読みだす() {
+ assertThat(map.size(), is(6));
+
+ int i = 0;
+ for (Date key : map.keySet()) {
+ assertThat(sdf.format(key), is(values[i++]));
+ }
+ }
+ }
+
+ public static class Keyとvalueのセット {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ ElementMapTRKPT map = null;
+ long timeL;
+
+ /*
+ *
+ * 614.90
+ * 615.00
+ * 615.03
+ */
+ static String[][] values = {
+ {"2017-05-29T01:23:18Z", "35.8812697884", "137.9952202085", null},
+ {"2017-05-29T01:23:21Z", "35.8811769169", "137.9951928835", "614.90"},
+ {"2017-05-29T01:23:24Z", "35.881112963", "137.9951796401", "615.00"},
+ {"2017-05-29T01:23:27Z", "35.881072646", "137.9951728508", "615.03"}
+ };
+
+ Element createElement(Document document, String[] values) {
+ Element trkpt = document.createElement("trkpt");
+ trkpt.setAttribute("lat", values[1]);
+ trkpt.setAttribute("lon", values[2]);
+ Element timeE = document.createElement("time");
+ timeE.appendChild(document.createTextNode(values[0]));
+ trkpt.appendChild(timeE);
+ if (values[3] != null) {
+ Element eleE = document.createElement("ele");
+ eleE.appendChild(document.createTextNode(values[3]));
+ trkpt.appendChild(eleE);
+ }
+ return trkpt;
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ Complementation.param_GpxOverwriteMagvar = true;
+
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ DOMImplementation domImpl=builder.getDOMImplementation();
+ Document document = domImpl.createDocument("","trkpt",null);
+
+ map = new ElementMapTRKPT();
+ for (int cnt = 4; cnt > 0; cnt--) {
+ map.put(new TagTrkpt(createElement(document, values[cnt - 1])));
+ }
+ }
+
+ @Test
+ public void コンテンツの数をチェック() {
+ assertThat(map.size(), is(4));
+ }
+
+ @Test
+ public void KEYが時間順に取り出せるか() {
+ int i = 0;
+ for (Date key : map.keySet()) {
+ try {
+ String s = sdf.format(ImportPicture.toUTCDate(values[i++][0]));
+ assertThat(sdf.format(key), is(s));
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Test
+ public void get_17() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:17Z"));
+ assertThat(tag, is(nullValue()));
+ }
+
+ @Test
+ public void get_18() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:18Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:18Z"));
+ assertThat(tag.eleStr, is(nullValue()));
+ assertThat(tag.lat, is(new Double(values[0][1])));
+ assertThat(tag.lon, is(new Double(values[0][2])));
+ assertThat(tag.magvarStr, is(nullValue()));
+ }
+
+ @Test
+ public void get_19() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:19Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:18Z"));
+ assertThat(tag.eleStr, is(nullValue()));
+ assertThat(tag.lat, is(new Double(values[0][1])));
+ assertThat(tag.lon, is(new Double(values[0][2])));
+ assertThat(tag.magvarStr, is(nullValue()));
+ }
+
+ @Test
+ public void get_20() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:20Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:18Z"));
+ assertThat(tag.eleStr, is(nullValue()));
+ assertThat(tag.lat, is(new Double(values[0][1])));
+ assertThat(tag.lon, is(new Double(values[0][2])));
+ assertThat(tag.magvarStr, is(nullValue()));
+ }
+
+ @Test
+ public void get_21() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:21Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:21Z"));
+ assertThat(tag.eleStr, is("614.90"));
+ assertThat(tag.lat, is(new Double(values[1][1])));
+ assertThat(tag.lon, is(new Double(values[1][2])));
+ assertThat(tag.magvarStr, is(notNullValue()));
+ }
+
+ @Test
+ public void get_22() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:22Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:21Z"));
+ assertThat(tag.eleStr, is("614.90"));
+ assertThat(tag.lat, is(new Double(values[1][1])));
+ assertThat(tag.lon, is(new Double(values[1][2])));
+ assertThat(tag.magvarStr, is(notNullValue()));
+ }
+
+ @Test
+ public void get_23() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:23Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:21Z"));
+ assertThat(tag.eleStr, is("614.90"));
+ assertThat(tag.lat, is(new Double(values[1][1])));
+ assertThat(tag.lon, is(new Double(values[1][2])));
+ assertThat(tag.magvarStr, is(notNullValue()));
+ }
+
+ @Test
+ public void get_24() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:24Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:24Z"));
+ assertThat(tag.eleStr, is("615.00"));
+ assertThat(tag.lat, is(new Double(values[2][1])));
+ assertThat(tag.lon, is(new Double(values[2][2])));
+ assertThat(tag.magvarStr, is(notNullValue()));
+ }
+
+ @Test
+ public void get_25() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:25Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:24Z"));
+ assertThat(tag.eleStr, is("615.00"));
+ assertThat(tag.lat, is(new Double(values[2][1])));
+ assertThat(tag.lon, is(new Double(values[2][2])));
+ assertThat(tag.magvarStr, is(notNullValue()));
+ }
+
+ @Test
+ public void get_26() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:26Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:24Z"));
+ assertThat(tag.eleStr, is("615.00"));
+ assertThat(tag.lat, is(new Double(values[2][1])));
+ assertThat(tag.lon, is(new Double(values[2][2])));
+ assertThat(tag.magvarStr, is(notNullValue()));
+ }
+
+ @Test
+ public void get_27() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:27Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:27Z"));
+ assertThat(tag.eleStr, is("615.03"));
+ assertThat(tag.lat, is(new Double(values[3][1])));
+ assertThat(tag.lon, is(new Double(values[3][2])));
+ assertThat(tag.magvarStr, is(notNullValue()));
+ }
+
+ @Test
+ public void get_28() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:28Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:27Z"));
+ assertThat(tag.eleStr, is("615.03"));
+ assertThat(tag.lat, is(new Double(values[3][1])));
+ assertThat(tag.lon, is(new Double(values[3][2])));
+ assertThat(tag.magvarStr, is(notNullValue()));
+ }
+
+ @Test
+ public void get_30() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:30Z"));
+ assertThat(sdf.format(tag.time), is("2017-05-29T10:23:27Z"));
+ assertThat(tag.eleStr, is("615.03"));
+ assertThat(tag.lat, is(new Double(values[3][1])));
+ assertThat(tag.lon, is(new Double(values[3][2])));
+ assertThat(tag.magvarStr, is(notNullValue()));
+ }
+
+ @Test
+ public void get_31() throws ParseException {
+ TagTrkpt tag = map.getValue(ImportPicture.toUTCDate("2017-05-29T01:23:31Z"));
+ assertThat(tag, is(nullValue()));
+ }
+ }
+
+ public static class タイムスタンプの書式 {
+ @Test
+ public void EXIF時刻書式テスト() throws Exception {
+ String dateTimeOriginal = "2017:06:30 09:59:59";
+ Date time = ImportPicture.toEXIFDate(dateTimeOriginal);
+ assertThat(ImportPicture.toEXIFString(time), is("2017:06:30 09:59:59"));
+ assertThat(ImportPicture.toUTCString(time), is("2017-06-30T00:59:59Z"));
+ DateFormat dfUTC = new SimpleDateFormat(ImportPicture.TIME_FORMAT_STRING);
+ assertThat(dfUTC.format(time), is("2017-06-30T09:59:59Z"));
+ }
+ }
+}
diff --git a/src/test/java/osm/jp/gpx/ElementMapTRKSEGTest.java b/src/test/java/osm/jp/gpx/ElementMapTRKSEGTest.java
new file mode 100644
index 0000000..fb794e4
--- /dev/null
+++ b/src/test/java/osm/jp/gpx/ElementMapTRKSEGTest.java
@@ -0,0 +1,69 @@
+package osm.jp.gpx;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.Date;
+import javax.xml.parsers.ParserConfigurationException;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.w3c.dom.DOMException;
+import org.xml.sax.SAXException;
+
+public class ElementMapTRKSEGTest {
+
+ @RunWith(Theories.class)
+ public static class 各種GPXファイルを食わせる {
+ static class Fixture {
+ String gpxSourcePath; // GPXファイル(オリジナル)
+ int segCount; // GPXファイルに含まれるTRKSEGノードの数
+
+ public Fixture(String gpxSourcePath, int segCount) {
+ this.gpxSourcePath = gpxSourcePath;
+ this.segCount = segCount;
+ }
+
+ @Override
+ public String toString() {
+ String msg = "テストパターン : \n";
+ msg += "\tgpxSourcePath = "+ gpxSourcePath +"\n";
+ msg += "\tsegCount = "+ segCount;
+ return msg;
+ }
+ }
+
+ @DataPoints
+ public static Fixture[] datas = {
+ new Fixture("testdata/20170517.gpx", 1),
+ new Fixture("testdata/20170518.gpx", 1),
+ new Fixture("testdata/muiltiTRK.GarminColorado.gpx.xml", 3),
+ new Fixture("testdata/muiltiTRKSEG.GarminColorado.gpx.xml", 3),
+ new Fixture("testdata/muiltiTRKSEG.noNameSpace.gpx.xml", 3),
+ new Fixture("testdata/multiTRKSEG.eTrex_20J.gpx.xml", 3),
+ new Fixture("testdata/multiTRKSEGreverse.eTrex_20J.gpx.xml", 3),
+ };
+
+ @Theory
+ public void TRKSEGを読み込む(Fixture dataset) {
+ try {
+ ElementMapTRKSEG mapTRKSEG = new ElementMapTRKSEG();
+ mapTRKSEG.parse(new File(dataset.gpxSourcePath));
+ mapTRKSEG.printinfo();
+ System.out.println("GPX file: "+ dataset.gpxSourcePath);
+ assertThat(mapTRKSEG.size(), is(dataset.segCount));
+ for (Date key : mapTRKSEG.keySet()) {
+ assertThat(key, is(notNullValue()));
+ }
+ }
+ catch (IOException | ParseException | ParserConfigurationException | DOMException | SAXException e) {
+ fail();
+ }
+ }
+ }
+}
diff --git a/src/test/java/osm/jp/gpx/ImportPictureTest.java b/src/test/java/osm/jp/gpx/ImportPictureTest.java
new file mode 100644
index 0000000..d20a355
--- /dev/null
+++ b/src/test/java/osm/jp/gpx/ImportPictureTest.java
@@ -0,0 +1,740 @@
+package osm.jp.gpx;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
+import org.apache.commons.imaging.Imaging;
+import org.apache.commons.imaging.common.ImageMetadata;
+import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
+import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
+import org.apache.commons.imaging.formats.tiff.TiffImageMetadata.GPSInfo;
+import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants;
+import org.junit.runner.*;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+
+public class ImportPictureTest {
+ static class Expecter {
+ String value;
+ boolean expect;
+ String timeStr;
+ double latD;
+ double lonD;
+ boolean magvar;
+
+ public Expecter(String value, boolean expect, String timeStr, double latD, double lonD, boolean magvar) {
+ this.value = value;
+ this.expect = expect;
+ this.timeStr = timeStr;
+ this.latD = latD;
+ this.lonD = lonD;
+ this.magvar = magvar;
+ }
+ }
+
+ static class Fixture {
+ String comment; // テスト概要(コメント)
+ String tarFilePath; // TARデータ
+ String gpxSourcePath; // GPXファイル(オリジナル)
+ String gpxDestinationPath; // GPXファイル(配置先)
+ String iniFilePath; // iniファイル
+ Expecter[] expecters;
+
+ public Fixture(
+ String comment,
+ String tarFilePath,
+ String gpxSourcePath,
+ String gpxDestinationPath,
+ String iniFilePath,
+ Expecter[] expecters
+ ) {
+ this.comment = comment;
+ this.tarFilePath = tarFilePath;
+ this.gpxSourcePath = gpxSourcePath;
+ this.gpxDestinationPath = gpxDestinationPath;
+ this.iniFilePath = iniFilePath;
+ this.expecters = expecters;
+ }
+
+ @Override
+ public String toString() {
+ String msg = "テストパターン : "+ comment + "\n";
+ msg += "\ttarFilePath = "+ tarFilePath +"\n";
+ msg += "\tgpxSourcePath = "+ gpxSourcePath +"\n";
+ msg += "\tgpxDestinationPath = "+ gpxDestinationPath +"\n";
+ msg += "\tiniFilePath = "+ iniFilePath;
+ return msg;
+ }
+ }
+
+
+ @RunWith(Theories.class)
+ public static class 各種カメラGPXファイル {
+
+ @DataPoints
+ public static Fixture[] datas = {
+ // 1
+ new Fixture(
+ "[A1].SONYカメラの場合.FILE_UPDATE時間を基準にして時間外のファイルはコピー対象外の時",
+ "testdata/Sony20170518.tar.gz",
+ "testdata/20170518.gpx",
+ "testdata/cameradata/20170518.gpx",
+ "testdata/AdjustTime.20170518.A1.ini",
+ new Expecter[] {
+ new Expecter("10170518/20170518_.gpx", true, null, 90.0D, 180.0D, false),
+ new Expecter("10170518/DSC05183.JPG", false, null, 90.0D, 180.0D, false),
+ new Expecter("10170518/DSC05184.JPG", true, "2017:05:18 09:34:44", 35.4367520000D, 139.4082730000D, true),
+ new Expecter("10170518/DSC05196.JPG", true, "2017:05:18 09:37:32", 35.4376820000D, 139.4085150000D, true),
+ new Expecter("10170518/DSC05204.JPG", true, "2017:05:18 09:46:48", 35.4368560000D, 139.4082190000D, true),
+ new Expecter("10170518/DSC05205.JPG", false, null, 90.0D, 180.0D, false),
+ }
+ ),
+ // 2
+ new Fixture(
+ "[A2].SONYカメラの場合.FILE_UPDATE時間を基準にして時間外のファイルもコピーする時",
+ "testdata/Sony20170518.tar.gz",
+ "testdata/20170518.gpx",
+ "testdata/cameradata/20170518.gpx",
+ "testdata/AdjustTime.20170518.A2.ini",
+ new Expecter[] {
+ new Expecter("10170518/20170518_.gpx", true, null, 90.0D, 180.0D, false),
+ new Expecter("10170518/DSC05183.JPG", true, "2017:05:18 09:16:48", 90.0D, 180.0D, true),
+ new Expecter("10170518/DSC05184.JPG", true, "2017:05:18 09:34:44", 35.4367520000D, 139.4082730000D, true),
+ new Expecter("10170518/DSC05196.JPG", true, "2017:05:18 09:37:32", 35.4376820000D, 139.4085150000D, true),
+ new Expecter("10170518/DSC05204.JPG", true, "2017:05:18 09:46:48", 35.4368560000D, 139.4082190000D, true),
+ new Expecter("10170518/DSC05205.JPG", true, "2017:05:18 09:48:04", 90.0D, 180.0D, true),
+ }
+ ),
+ // 3.
+ new Fixture(
+ "[B1].WiMiUSカメラの場合.FILE_UPDATE時間を基準にして時間外のファイルはコピー対象外の時",
+ "testdata/WiMiUS20170518.tar.gz",
+ "testdata/20170518.gpx",
+ "testdata/cameradata/20170518.gpx",
+ "testdata/AdjustTime.20170518.B1.ini",
+ new Expecter[] {
+ new Expecter("cameradata/20170518_.gpx", true, null, 90.0D, 180.0D, false),
+ new Expecter("cameradata/20170518_092031A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("cameradata/20170518_094226A_snap.jpg", true, "2017:05:18 09:42:26", 35.4366860000D, 139.4082650000D, true),
+ new Expecter("cameradata/20170518_094737A.jpg", true, "2017:05:18 09:47:36", 35.4368200000D, 139.4082810000D, true),
+ new Expecter("cameradata/20170518_094827A.jpg", false, null, 90.0D, 180.0D, false),
+ }
+ ),
+ // 4.
+ new Fixture(
+ "[B2].WiMiUSカメラの場合.FILE_UPDATE時間を基準にして時間外のファイルもコピーする時",
+ "testdata/WiMiUS20170518.tar.gz",
+ "testdata/20170518.gpx",
+ "testdata/cameradata/20170518.gpx",
+ "testdata/AdjustTime.20170518.B2.ini",
+ new Expecter[] {
+ new Expecter("cameradata/20170518_.gpx", true, null, 90.0D, 180.0D, false),
+ new Expecter("cameradata/20170518_092031A.jpg", true, "2017:05:18 09:20:30", 90.0D, 180.0D, true),
+ new Expecter("cameradata/20170518_094226A_snap.jpg", true, "2017:05:18 09:42:26", 35.4366860000D, 139.4082650000D, true),
+ new Expecter("cameradata/20170518_094737A.jpg", true, "2017:05:18 09:47:36", 35.4368200000D, 139.4082810000D, true),
+ new Expecter("cameradata/20170518_094827A.jpg", true, "2017:05:18 09:48:26", 90.0D, 180.0D, true),
+ }
+ ),
+ // 5.
+ new Fixture(
+ "[M1a].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.GarminColorado",
+ "testdata/separate.tar.gz",
+ "testdata/muiltiTRK.GarminColorado.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M1a.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
+ }
+ ),
+
+ new Fixture(
+ "[M1b].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.GarminColorado",
+ "testdata/separate.tar.gz",
+ "testdata/muiltiTRK.GarminColorado.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M1b.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:06", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:10", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:14", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:44", 90.0D, 180.0D, true),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
+ }
+ ),
+
+ new Fixture(
+ "[M1c].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.GarminColorado",
+ "testdata/separate.tar.gz",
+ "testdata/muiltiTRK.GarminColorado.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M1c.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339846227D, 138.0625408050D, true),
+ }
+ ),
+
+ new Fixture(
+ "[M1d].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.GarminColorado",
+ "testdata/separate.tar.gz",
+ "testdata/muiltiTRK.GarminColorado.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M1d.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:05", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:09", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:15", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:45", 90.0D, 180.0D, true),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339846227D, 138.0625408050D, true),
+ }
+ ),
+
+
+ new Fixture(
+ "[M2a].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.eTrex_20J",
+ "testdata/separate.tar.gz",
+ "testdata/multiTRKSEG.eTrex_20J.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M2a.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
+ }
+ ),
+
+ new Fixture(
+ "[M2b].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.eTrex_20J",
+ "testdata/separate.tar.gz",
+ "testdata/multiTRKSEG.eTrex_20J.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M2b.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:06", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:10", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:14", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:44", 90.0D, 180.0D, true),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
+ }
+ ),
+
+ new Fixture(
+ "[M2c].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.eTrex_20J",
+ "testdata/separate.tar.gz",
+ "testdata/multiTRKSEG.eTrex_20J.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M2c.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339889813D, 138.0625394639D, true),
+ }
+ ),
+
+ new Fixture(
+ "[M2d].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.eTrex_20J",
+ "testdata/separate.tar.gz",
+ "testdata/multiTRKSEG.eTrex_20J.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M2d.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:05", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:09", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:15", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:45", 90.0D, 180.0D, true),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339889813D, 138.0625394639D, true),
+ }
+ ),
+
+ new Fixture(
+ "[M3a].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.eTrex_20Jreverse",
+ "testdata/separate.tar.gz",
+ "testdata/multiTRKSEGreverse.eTrex_20J.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M2a.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
+ }
+ ),
+
+ new Fixture(
+ "[M3b].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.eTrex_20Jreverse",
+ "testdata/separate.tar.gz",
+ "testdata/multiTRKSEGreverse.eTrex_20J.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M2b.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:06", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:10", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:14", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:44", 90.0D, 180.0D, true),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
+ }
+ ),
+
+ new Fixture(
+ "[M3c].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.eTrex_20Jreverse",
+ "testdata/separate.tar.gz",
+ "testdata/multiTRKSEGreverse.eTrex_20J.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M2c.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
+ new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339889813D, 138.0625394639D, true),
+ }
+ ),
+
+ new Fixture(
+ "[M3d].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.eTrex_20Jreverse",
+ "testdata/separate.tar.gz",
+ "testdata/multiTRKSEGreverse.eTrex_20J.gpx.xml",
+ "testdata/cameradata/separate.gpx",
+ "testdata/AdjustTime.M2d.separate.ini",
+ new Expecter[] {
+ // GPX file
+ new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
+
+ // out of time ( - 2017-05-29T01:23:18)
+ new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:05", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
+
+ // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
+ new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
+ new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
+ new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
+
+ // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
+ new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:09", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
+
+ // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
+ new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
+ new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
+
+ // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
+ new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:15", 90.0D, 180.0D, true),
+ new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:45", 90.0D, 180.0D, true),
+
+ // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
+ new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
+ new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339889813D, 138.0625394639D, true),
+ }
+ ),
+ };
+
+ @Theory
+ public void パラメータテスト(Fixture dataset) throws Exception {
+ ImportPictureTest.setup(dataset);
+ ImportPictureTest.testdo(dataset.iniFilePath);
+ //SimpleDateFormat format = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.UK);
+
+ Expecter[] es = dataset.expecters;
+ AppParameters params = new AppParameters(dataset.iniFilePath);
+ File outDir = new File(params.getProperty(AppParameters.IMG_OUTPUT_FOLDER));
+ for (Expecter e : es) {
+ File file = new File(outDir, e.value);
+ System.out.println("[JUnit.debug] assert file='"+ file.getAbsolutePath() +"'");
+ assertThat(file.exists(), is(e.expect));
+ if (e.timeStr != null) {
+ // JPEG メタデータが存在すること
+ ImageMetadata meta = Imaging.getMetadata(file);
+ // メタデータは インスタンスJpegImageMetadata であること
+ assertThat((meta instanceof JpegImageMetadata), is(true));
+ JpegImageMetadata jpegMetadata = (JpegImageMetadata)meta;
+ assertNotNull(jpegMetadata);
+ // EXIFデータが存在すること
+ TiffImageMetadata exif = jpegMetadata.getExif();
+ assertNotNull(exif);
+ // EXIF-TIME が正しく設定されていること
+ String exifTime = ImportPicture.toEXIFString(ImportPicture.toEXIFDate(exif.getFieldValue(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL)[0]));
+ System.out.println("[debug] exifTime = '"+ exifTime +"' <--> '" + e.timeStr + "'");
+ assertThat(exifTime, is(e.timeStr));
+ // LAT,LON
+ GPSInfo gpsInfo = exif.getGPS();
+ if (e.latD != 90.0D) {
+ assertThat(comparePosition(gpsInfo.getLatitudeAsDegreesNorth()), is(comparePosition(e.latD)));
+ }
+ if (e.lonD != 180.0D) {
+ assertThat(comparePosition(gpsInfo.getLongitudeAsDegreesEast()), is(comparePosition(e.lonD)));
+ }
+ }
+ }
+ }
+
+ static String comparePosition(double b) {
+ return String.format("%.4f", b);
+ }
+ }
+
+ static void setup(Fixture dataset) throws IOException {
+ System.out.println(dataset.toString());
+
+ // カメラディレクトリを削除する
+ File dir = new File("testdata/cameradata");
+ if (dir.exists()) {
+ ImportPictureTest.delete(dir);
+ }
+ File outDir = new File("testdata/output");
+ if (outDir.exists()) {
+ ImportPictureTest.delete(outDir);
+ }
+ outDir.mkdir();
+
+ // カメラディレクトリを作成する
+ ImportPictureTest.uncompress(new File(dataset.tarFilePath), new File("testdata/cameradata"));
+
+ // GPXファイルをセット
+ try (FileInputStream inStream = new FileInputStream(new File(dataset.gpxSourcePath));
+ FileOutputStream outStream = new FileOutputStream(new File(dataset.gpxDestinationPath));
+ FileChannel inChannel = inStream.getChannel();
+ FileChannel outChannel = outStream.getChannel())
+ {
+ inChannel.transferTo(0, inChannel.size(), outChannel);
+ }
+ }
+
+ /**
+ * 実行する
+ * @throws Exception
+ */
+ static void testdo(String iniFilePath) {
+ try {
+ String[] argv = {iniFilePath};
+ ImportPicture.main(argv);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ fail("Exceptionが発生した。");
+ }
+ }
+
+ /**
+ * *.tar.gz解凍
+ * ファイル更新日時をオリジナルと同じにします。
+ * @param tazFile 解凍する*.tar.gzファイル
+ * @param dest 解凍先フォルダ
+ * @throws IOException
+ */
+ public static void uncompress(File tazFile, File dest) throws IOException {
+ dest.mkdir();
+
+ try (TarArchiveInputStream tarIn = new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(tazFile))))) {
+ TarArchiveEntry tarEntry = tarIn.getNextTarEntry();
+ while (tarEntry != null) {
+ File destPath = new File(dest, tarEntry.getName());
+ //System.out.println("uncompress: " + destPath.getCanonicalPath());
+ if (tarEntry.isDirectory()) {
+ destPath.mkdirs();
+ }
+ else {
+ File dir = new File(destPath.getParent());
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+ destPath.createNewFile();
+ byte[] btoRead = new byte[1024];
+ try (BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(destPath))) {
+ int len = 0;
+ while ((len = tarIn.read(btoRead)) != -1) {
+ bout.write(btoRead, 0, len);
+ }
+ }
+ destPath.setLastModified(tarEntry.getLastModifiedDate().getTime());
+ btoRead = null;
+ }
+ tarEntry = tarIn.getNextTarEntry();
+ }
+ }
+ }
+
+ public static void delete(File file) throws IOException {
+ if (!file.exists()) {
+ System.out.println("ERROR: ファイルまたはディレクトリが見つかりませんでした。");
+ throw new IOException("File not found.");
+ }
+
+ if (file.isDirectory()) {
+ File files[] = file.listFiles();
+ if (files != null) {
+ for (File file1 : files) {
+ delete(file1); // 再帰呼び出し
+ }
+ }
+ }
+ if (!file.delete()) {
+ System.out.println("ERROR: ファイルは削除できませんでした。 '" + file.getAbsolutePath() +"'");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/osm/jp/gpx/RestampTest.java b/src/test/java/osm/jp/gpx/RestampTest.java
new file mode 100644
index 0000000..caa8c3c
--- /dev/null
+++ b/src/test/java/osm/jp/gpx/RestampTest.java
@@ -0,0 +1,56 @@
+package osm.jp.gpx;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author yuu
+ */
+public class RestampTest {
+
+ public RestampTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of main method, of class Restamp.
+ */
+ @Test
+ public void testMain() {
+ try {
+ System.out.println("main");
+ String[] argv = new String[]{
+ "/home/yuu/Desktop/OSM/20180325_横浜新道/img",
+ "000033.jpg",
+ "2018-03-25_12:20:32",
+ "003752.jpg",
+ "2018-03-25_13:22:42"
+ };
+ Restamp.main(argv);
+ }
+ catch (Exception e) {
+ fail();
+ }
+ }
+
+}
diff --git a/src/test/java/osm/jp/gpx/UnZip.java b/src/test/java/osm/jp/gpx/UnZip.java
new file mode 100644
index 0000000..2b6a72f
--- /dev/null
+++ b/src/test/java/osm/jp/gpx/UnZip.java
@@ -0,0 +1,75 @@
+package osm.jp.gpx;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class UnZip {
+
+ /**
+ * Zipファイルを展開します
+ * @param aZipFile zipファイル
+ * @param aOutDir 出力先ディレクトリ
+ * @throws java.io.IOException
+ */
+ public static void decode(File aZipFile, String aOutDir) throws IOException {
+ FileInputStream fileIn = null;
+ FileOutputStream fileOut = null;
+ ZipInputStream zipIn = null;
+
+ try {
+ File outDir = new File(aOutDir);
+ outDir.mkdirs();
+
+ fileIn = new FileInputStream(aZipFile);
+ zipIn = new ZipInputStream(fileIn);
+
+ ZipEntry entry = null;
+ while ((entry = zipIn.getNextEntry()) != null) {
+ if (entry.isDirectory()) {
+ String relativePath = entry.getName();
+ outDir = new File(outDir, relativePath);
+ outDir.mkdirs();
+ }
+ else {
+ String relativePath = entry.getName();
+ File outFile = new File( outDir, relativePath );
+
+ File parentFile = outFile.getParentFile();
+ parentFile.mkdirs();
+
+ fileOut = new FileOutputStream( outFile );
+
+ byte[] buf = new byte[ 256 ];
+ int size = 0;
+ while ((size = zipIn.read(buf)) > 0){
+ fileOut.write(buf, 0, size);
+ }
+ fileOut.close();
+ fileOut = null;
+ }
+ zipIn.closeEntry();
+ }
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ finally {
+ if (fileIn != null) {
+ try {
+ fileIn.close();
+ }
+ catch (IOException e) {}
+ }
+ if (fileOut != null) {
+ try {
+ fileOut.close();
+ }
+ catch(IOException e) {}
+ }
+ zipIn.close();
+ }
+ }
+}
diff --git a/src/test/resources/AdjustTime.ini b/src/test/resources/AdjustTime.ini
new file mode 100644
index 0000000..83fb9a9
--- /dev/null
+++ b/src/test/resources/AdjustTime.ini
@@ -0,0 +1,17 @@
+#by AdjustTime
+#Tue Oct 22 11:27:01 JST 2019
+GPX.OVERWRITE_MAGVAR=false
+IMG.BASE_FILE=00009.jpg
+GPX.SOURCE_FOLDER=/home/yuu/work/mapping/Unmapped_2019-08-24_\u4E2D\u5C71\u9053_\u7B20\u53D6\u5CE0/GPX/2019-08-24 15.44.09 Day.gpx
+IMG.SOURCE_FOLDER=/home/yuu/work/mapping/Unmapped_2019-08-24_\u4E2D\u5C71\u9053_\u7B20\u53D6\u5CE0/img/20190824_132842A
+GPX.OUTPUT_SPEED=false
+IMG.OUTPUT_FOLDER=/home/yuu/work/mapping/Unmapped_2019-08-24_\u4E2D\u5C71\u9053_\u7B20\u53D6\u5CE0/Movie
+GPX.noFirstNode=true
+GPX.gpxSplit=true
+IMG.OUTPUT=true
+GPX.OUTPUT_WPT=false
+GPX.REUSE=false
+IMG.TIME=2019-08-24T04\:29\:17Z
+IMG.OUTPUT_EXIF=true
+IMG.OUTPUT_ALL=false
+GPX.BASETIME=FILE_UPDATE