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 ) +
+
+ +
+
+ embedded diagram image + + \ 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++])); + } + } + } + + +}