diff --git a/importPicture/doc/ImportPicture.class.violet.html b/importPicture/doc/ImportPicture.class.violet.html
new file mode 100644
index 0000000..83be5c1
--- /dev/null
+++ b/importPicture/doc/ImportPicture.class.violet.html
@@ -0,0 +1,1024 @@
+
+
+
+
+
+
+
+
+ This file was generated with Violet UML Editor 2.1.0.
+ ( View Source / Download Violet )
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/importPicture/src/osm/jp/gpx/ElementMapTRKPT.java b/importPicture/src/osm/jp/gpx/ElementMapTRKPT.java
new file mode 100644
index 0000000..15bc6d3
--- /dev/null
+++ b/importPicture/src/osm/jp/gpx/ElementMapTRKPT.java
@@ -0,0 +1,141 @@
+package osm.jp.gpx;
+
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+@SuppressWarnings("serial")
+public class ElementMapTRKPT extends TreeMap {
+ public static final long DIFF_MAE_TIME = 3000L; // before 3 secound
+
+ public ElementMapTRKPT() {
+ super(new TimeComparator());
+ }
+
+ /**
+ * 拡張put value:ElementをputするとElement内のtimeを読み取ってkeyとしてsuper.put(key,value)する。
+ * @param value
+ * @return keyとして登録したtime:Date
+ * @throws ParseException
+ * @throws DOMException
+ */
+ public Date put(Element value) throws DOMException, ParseException {
+ NodeList nodes3 = value.getChildNodes();
+ for (int i3=0; i3 < nodes3.getLength(); i3++) {
+ Node node4 = nodes3.item(i3);
+ if (node4.getNodeName().equals("time")) {
+ NodeList nodes4 = node4.getChildNodes(); // 子ノードを取得
+ for (int i4=0; i4< nodes4.getLength(); i4++) {
+ Node node5 = nodes4.item(i4);
+ if (node5 != null) {
+ if (node5.getNodeType() == Node.TEXT_NODE) {
+ Date time = ImportPicture.dfuk.parse(node5.getNodeValue());
+ this.put(time, value);
+ return time;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 指定時刻(jptime)のTRKPTエレメントを取り出す。
+ *
+ * @param jptime 指定する日時
+ * @return エレメントTRKPT。指定時刻に対応するノードがないときはnullを返す。
+ * @throws ParseException
+ */
+ public Element get(Date jptime) throws ParseException {
+ Element imaE = getTrkpt(jptime);
+ if (imaE != null) {
+ Element maeE = getMaeTrkpt(new TagTrkpt(imaE));
+ if (maeE != null) {
+ Complementation comp = new Complementation(imaE, maeE);
+
+ // がなければ、
+ // 直前の位置と、現在地から進行方向を求める
+ // 経度(longitude)と経度から進行方向を求める
+ if (Complementation.param_GpxOverwriteMagvar) {
+ comp.complementationMagvar();
+ }
+
+ // 緯度・経度と時間差から速度(km/h)を求める
+ if (Complementation.param_GpxOutputSpeed) {
+ comp.complementationSpeed();
+ }
+ imaE = (Element)(comp.imaTag.trkpt.cloneNode(true));
+ }
+ }
+ return imaE;
+ }
+
+ /**
+ * [map]から指定した時刻のエレメントを取り出す。
+ * GPX時刻との差が10分以上は無効
+ *
+ * @param mapTRKPT
+ * @param jptime
+ * @return エレメント
+ * @throws ParseException
+ */
+ private Element getTrkpt(Date jptime) throws ParseException {
+ long sa = 2L * 3600000L;
+ long jpt = jptime.getTime();
+
+ Element ret = null;
+
+ Set keySet = this.keySet(); //すべてのキー値を取得
+ Iterator keyIte = keySet.iterator();
+ while (keyIte.hasNext()) {
+ Date time = keyIte.next();
+ long t = time.getTime();
+
+ if (Math.abs(jpt - t) < sa) {
+ sa = Math.abs(jpt - t);
+ ret = super.get(time);
+ }
+ }
+
+ // GPX時刻との差が10分以内なら有効
+ if (sa < (60000L * 10L)) {
+ return ret;
+ }
+ return null;
+ }
+
+ private Element getMaeTrkpt(TagTrkpt imaTrkpt) throws ParseException {
+ Element ret = null;
+ long diffTime = 2L * 3600000L; // 2時間
+ long jpt = imaTrkpt.time.getTime() - DIFF_MAE_TIME;
+
+ Set keySet = this.keySet(); //すべてのキー値を取得
+ Iterator keyIte = keySet.iterator();
+ while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得
+ Date time = keyIte.next();
+ long t = time.getTime();
+
+ if (Math.abs(jpt - t) < diffTime) {
+ diffTime = Math.abs(jpt - t);
+ ret = super.get(time);
+ }
+ }
+
+ // GPX時刻との差が10分以内なら有効
+ if (diffTime < (60000L * 10L)) {
+ // 元の時刻との差が1秒以上あること
+ if (diffTime < (imaTrkpt.time.getTime() - 1000)) {
+ return ret;
+ }
+ }
+ return null;
+ }
+}
diff --git a/importPicture/src/osm/jp/gpx/ImportPicture.java b/importPicture/src/osm/jp/gpx/ImportPicture.java
index e622330..24a5a44 100644
--- a/importPicture/src/osm/jp/gpx/ImportPicture.java
+++ b/importPicture/src/osm/jp/gpx/ImportPicture.java
@@ -11,6 +11,7 @@
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TimeZone;
@@ -298,7 +299,6 @@
public boolean param_GpxOutputWpt = true;
public boolean param_ImgOutputAll = false;
public String param_GpxSourceFolder = ".";
- public static final long DIFF_MAE_TIME = 3000L; // before 3 secound
@Override
public void run() {
@@ -349,7 +349,6 @@
DocumentBuilderFactory factory;
DocumentBuilder builder;
Node gpx;
- boolean header = true; // ファイルヘッダの部分を出力するかどうかを示すフラグ
String fileName = gpxFile.getName();
String iStr = fileName.substring(0, fileName.length() - 4);
@@ -387,8 +386,7 @@
*
*
*/
- TreeMap mapTRKPT = new TreeMap();
- TreeMap mapTRKSEG = new TreeMap();
+ TreeMap mapTRKSEG = new TreeMap();
Element trk = null;
gpx = builder.parse(gpxFile).getFirstChild();
document = gpx.getOwnerDocument();
@@ -397,90 +395,68 @@
Node node2 = nodes.item(i);
if (node2.getNodeName().equals("trk")) {
trk = (Element) node2;
- long gpxStartTimeL = (new Date()).getTime();
NodeList nodes1 = trk.getChildNodes();
for (int i1=0; i1 < nodes1.getLength(); i1++) {
Node nodeTRKSEG = nodes1.item(i1);
if (nodeTRKSEG.getNodeName().equals("trkseg")) {
- Element newTRKSEG = document.createElement("trkseg");
- Element trkseg = (Element) nodeTRKSEG;
- NodeList nodes2 = trkseg.getChildNodes();
- long trksegStartTimeL = (new Date()).getTime(); // 対象とする開始時刻(現在時刻)
+ //Element newTRKSEG = document.createElement("trkseg");
+ NodeList nodes2 = nodeTRKSEG.getChildNodes();
+
+ ElementMapTRKPT mapTRKPT = new ElementMapTRKPT();
+ Date trksegStartTime = new Date(); // 対象とする開始時刻(現在時刻)
for (int i2=0; i2 < nodes2.getLength(); i2++) {
Node nodeTRKPT = nodes2.item(i2);
if (nodeTRKPT.getNodeName().equals("trkpt")) {
if (param_GpxNoFirstNode && (i2 == 0)) {
continue;
}
- Element trkpt = (Element) nodeTRKPT;
-
- NodeList nodes3 = trkpt.getChildNodes();
- for (int i3=0; i3 < nodes3.getLength(); i3++) {
- Node node4 = nodes3.item(i3);
- if (node4.getNodeName().equals("time")) {
- Element time = (Element) node4;
- NodeList nodes4 = time.getChildNodes(); // 子ノードを取得
- for (int i4=0; i4< nodes4.getLength(); i4++) {
- Node node5 = nodes4.item(i4);
- if (node5 != null) {
- if (node5.getNodeType() == Node.TEXT_NODE) {
- String timeStr = node5.getNodeValue();
- long timeL = dfuk.parse(timeStr).getTime();
- if (trksegStartTimeL > timeL) {
- trksegStartTimeL = timeL;
- }
- mapTRKPT.put(timeL, getCopy(trkseg.getOwnerDocument(), trkpt));
- }
- }
- }
- }
- }
- newTRKSEG.appendChild(getCopy(document, nodeTRKPT));
+ Date time = mapTRKPT.put(getCopy(document, nodeTRKPT));
+ if (trksegStartTime.compareTo(time) < 0) {
+ trksegStartTime = time;
+ }
}
}
// からを削除する。
- trk.removeChild(nodeTRKSEG);
+ //trk.removeChild(nodeTRKSEG);
// に、新たなを追加する。
- trk.appendChild(newTRKSEG);
+ //trk.appendChild(newTRKSEG);
- mapTRKSEG.put(gpxStartTimeL, getCopy(document, newTRKSEG));
+ System.out.println("\tdebug: mapTRKSEG.put(k=" + dfjp.format(trksegStartTime) +", mapTRKPT)");
+ mapTRKSEG.put(trksegStartTime.getTime(), mapTRKPT);
+ //newTRKSEG = null;
}
}
}
}
// mapTRKSEGに時間順に格納されたを順次ひとつづつ処理する
- for (Entry mapEntry : mapTRKSEG.entrySet()) {
- Element newTRKSEG = mapEntry.getValue();
+ System.out.println("|--------------------------------|--------------------|--------------------|--------------|--------------|--------|------|------|");
+ System.out.println("| name | UpdateTime | GPStime | Latitude | Longitude | ele |magvar| km/h |");
+ System.out.println("|--------------------------------|--------------------|--------------------|--------------|--------------|--------|------|------|");
+ proc(imgDir, delta, mapTRKSEG, exif, gpx);
+ for (Map.Entry mapEntry : mapTRKSEG.entrySet()) {
+ System.out.println("\tdebug: k=" + dfjp.format(new Date(mapEntry.getKey().longValue())));
+
+ ElementMapTRKPT mapPT = mapEntry.getValue();
- // mapTRKPTに、を割り付ける
- trkptMap(newTRKSEG, mapTRKPT);
-
// の開始時刻と終了時刻を求める
- long segStartTimeL = (new Date()).getTime(); // の開始時刻
+ long segStartTimeL = new Date().getTime(); // の開始時刻
long segEndTimeL = 0L; // 対象とする終了時刻
- Set keySet = mapTRKPT.keySet(); //すべてのキー値を取得
- for (Long timeLong : keySet) {
- long gpxTime = timeLong;
- if (segStartTimeL > gpxTime) {
- segStartTimeL = gpxTime;
+ for (Entry entryPT : mapPT.entrySet()) {
+ Date key = entryPT.getKey();
+ if (segStartTimeL > key.getTime()) {
+ segStartTimeL = key.getTime();
}
- if (segEndTimeL < gpxTime) {
- segEndTimeL = gpxTime;
+ if (segEndTimeL < key.getTime()) {
+ segEndTimeL = key.getTime();
}
}
- if (header) {
- System.out.println("|--------------------------------|--------------------|--------------------|--------------|--------------|--------|------|------|");
- System.out.println("| name | UpdateTime | GPStime | Latitude | Longitude | ele |magvar| km/h |");
- System.out.println("|--------------------------------|--------------------|--------------------|--------------|--------------|--------|------|------|");
- header = false;
- }
System.out.println("|-------------------------|"+ dfjp.format(new Date(segStartTimeL)) + "-->"+ dfjp.format(new Date(segEndTimeL)) +"|");
- proc(imgDir, delta, segStartTimeL, segEndTimeL, mapTRKPT, exif, gpx);
+ //proc(imgDir, delta, segStartTimeL, segEndTimeL, mapPT, exif, gpx);
}
System.out.println("|--------------------------------|--------------------|--------------------|--------------|--------------|--------|------|------|");
@@ -508,7 +484,7 @@
* @throws ImageReadException
* @throws ImageWriteException
*/
- boolean proc(File dir, long delta, long gpxStartTime, long gpxEndTime, TreeMap map, boolean exifWrite, Node gpx) throws ParseException, ImageReadException, IOException, ImageWriteException {
+ boolean proc(File dir, long delta, TreeMap mapTRKSEG, boolean exifWrite, Node gpx) throws ParseException, ImageReadException, IOException, ImageWriteException {
DecimalFormat yearFormatter = new DecimalFormat("0000");
DecimalFormat monthFormatter = new DecimalFormat("00");
DecimalFormat dayFormatter = new DecimalFormat("00");
@@ -519,7 +495,7 @@
for (File image : files) {
System.out.print(String.format("|%-32s|", image.getName()));
if (image.isDirectory()) {
- ret = proc(image, delta, gpxStartTime, gpxEndTime, map, exifWrite, gpx);
+ ret = proc(image, delta, mapTRKSEG, exifWrite, gpx);
continue;
}
@@ -529,6 +505,8 @@
continue;
}
+ // itime <-- 画像ファイルの撮影時刻
+ // ファイルの更新日時/EXIFの撮影日時
Date itime = new Date(image.lastModified());
if (this.exifBase) {
ImageMetadata meta = Imaging.getMetadata(image);
@@ -546,20 +524,23 @@
long lastModifyTime = (new SimpleDateFormat("yyyy:MM:dd HH:mm:ss")).parse(dateTimeOriginal).getTime();
itime = new Date(lastModifyTime);
}
-
- // uktime <-- 画像撮影時刻に対応するGPX時刻
- Date uktime = new Date(itime.getTime() + delta);
System.out.print(String.format("%20s ", dfjp.format(itime)));
+
+ // uktime <-- 画像撮影時刻に対応するGPX時刻(補正日時)
+ Date uktime = new Date(itime.getTime() + delta);
System.out.print(String.format("%20s|", dfjp.format(uktime)));
+
+ /*
if ((uktime.getTime() < gpxStartTime) || (uktime.getTime() > gpxEndTime)) {
System.out.println(String.format("%20s ", "out of time."));
if (!this.param_ImgOutputAll) {
continue;
}
}
+ */
// 時刻uktimeにおけるをtrkptに追加する
- Element trkptE = trkpt(map, uktime);
+ Element trkptE = mapTRKPT.get(uktime);
String eleStr = "-";
String magvarStr = "-";
String speedStr = "-";
@@ -574,10 +555,6 @@
}
else {
trkptT = new TagTrkpt(trkptE);
-
- //Element wpt = createWptTag(image, uktime.getTime(), trkptE);
- //String latStr = trkptT.lat.toString();
- //String lonStr = trkptT.lon.toString();
latitude = trkptT.lat;
longitude = trkptT.lon;
@@ -768,6 +745,7 @@
* @param map
* @throws ParseException
*/
+ /*
public long trkptMap(Element trkseg, TreeMap map) throws ParseException {
dfuk.setTimeZone(TimeZone.getTimeZone("GMT"));
long gpxStartTimeL = (new Date()).getTime(); // 対象とする開始時刻(現在時刻)
@@ -804,104 +782,14 @@
}
return gpxStartTimeL;
}
+ */
-
- /**
- * <trkpt lat="35.32123832" lon="139.56965631">
- * <ele>47.20000076293945</ele>
- * <time>2012-06-15T03:00:29Z</time>
- * </trkpt>
- *DIFF_MAE_TIME
- * @return
- * @param map
- * @param jptime 画像ファイルの撮影日時 ミリ秒(日本時間)
- * @throws ParseException
- */
- public Element trkpt(TreeMap map, Date jptime) throws ParseException {
- // 指定した時刻のエレメント(imaTrkpt)を取得する
- Element imaE = getTrkpt(map, jptime);
- if (imaE != null) {
- Element maeE = getMaeTrkpt(map, new TagTrkpt(imaE));
- if (maeE != null) {
- Complementation comp = new Complementation(imaE, maeE);
- // がなければ、
- // 直前の位置と、現在地から進行方向を求める
- // 経度(longitude)と経度から進行方向を求める
- if (Complementation.param_GpxOverwriteMagvar) {
- comp.complementationMagvar();
- }
- // 緯度・経度と時間差から速度(km/h)を求める
- if (Complementation.param_GpxOutputSpeed) {
- comp.complementationSpeed();
- }
- imaE = (Element)(comp.imaTag.trkpt.cloneNode(true));
- }
- }
- return imaE;
- }
- /**
- * [map]から指定した時刻のエレメントを取り出す。
- * GPX時刻との差が10分以上は無効
- *
- * @param map
- * @param jptime
- * @return
- * @throws ParseException
- */
- public Element getTrkpt(TreeMap map, Date jptime) throws ParseException {
- long sa = 2L * 3600000L;
- long jpt = jptime.getTime();
-
- Element ret = null;
- Set keySet = map.keySet(); //すべてのキー値を取得
- Iterator keyIte = keySet.iterator();
- while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得
- Long time = keyIte.next();
- long t = time;
- if (Math.abs(jpt - t) < sa) {
- sa = Math.abs(jpt - t);
- ret = map.get(time);
- }
- }
- if (sa < (60000L * 10L)) {
- // GPX時刻との差が10分以内なら有効
- return ret;
- }
- return null;
- }
-
- public Element getMaeTrkpt(TreeMap map, TagTrkpt imaTrkpt) throws ParseException {
- Element ret = null;
- long diffTime = 2L * 3600000L; // 2時間
- long jpt = imaTrkpt.time.getTime() - DIFF_MAE_TIME;
-
- Set keySet = map.keySet(); //すべてのキー値を取得
- Iterator keyIte = keySet.iterator();
- while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得
- Long time = keyIte.next();
- long t = time;
-
- if (Math.abs(jpt - t) < diffTime) {
- diffTime = Math.abs(jpt - t);
- ret = map.get(time);
- }
- }
-
- if (diffTime < (60000L * 10L)) {
- // GPX時刻との差が10分以内なら有効
- if (diffTime < (imaTrkpt.time.getTime() - 1000)) {
- // 元の時刻との差が1秒以上あること
- return ret;
- }
- }
- return null;
- }
/**
* 対象は '*.JPG' のみ対象とする
diff --git a/importPicture/src/osm/jp/gpx/TimeComparator.java b/importPicture/src/osm/jp/gpx/TimeComparator.java
new file mode 100644
index 0000000..76c4547
--- /dev/null
+++ b/importPicture/src/osm/jp/gpx/TimeComparator.java
@@ -0,0 +1,21 @@
+package osm.jp.gpx;
+
+import java.util.Comparator;
+import java.util.Date;
+
+/**
+ * java.util.Date型をコレクションのKEYにした時に、時間順に並べ替える
+ *
+ * @author yuu
+ */
+public class TimeComparator implements Comparator
+{
+ /**
+ * 日付順にソート
+ */
+ @Override
+ public int compare(Date arg0, Date arg1) {
+ return arg0.compareTo(arg1);
+ }
+
+}
diff --git a/importPicture/test/osm/jp/gpx/ElementMapTRKPTTest.java b/importPicture/test/osm/jp/gpx/ElementMapTRKPTTest.java
new file mode 100644
index 0000000..e021131
--- /dev/null
+++ b/importPicture/test/osm/jp/gpx/ElementMapTRKPTTest.java
@@ -0,0 +1,71 @@
+package osm.jp.gpx;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.RunWith;
+
+@RunWith(Enclosed.class)
+public class ElementMapTRKPTTest {
+ public static class 時間順にプットされない場合 {
+ 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 (Iterator itr = map.keySet().iterator(); itr.hasNext(); ) {
+ Date key = itr.next();
+ 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++]));
+ }
+ }
+ }
+
+
+}