package osm.jp.gpx; import java.text.ParseException; import java.util.Date; import java.util.TreeMap; import org.w3c.dom.DOMException; @SuppressWarnings("serial") public class ElementMapTRKPT extends TreeMap<Date, TagTrkpt> { public static final long DIFF_MAE_TIME = 3000L; // before 3 secound public ElementMapTRKPT() { super(new TimeComparator()); } /** * 拡張put value:ElementをputするとElement内のtimeを読み取ってkeyとしてthis.put(key,value)する。 * @param tag * @code{ * <trkpt lat="36.4260153752" lon="138.0117778201"> * <ele>614.90</ele> * <time>2017-05-21T23:02:16Z</time> * <hdop>0.5</hdop> * </trkpt> * } * @return keyとして登録したtime:Date * @throws ParseException * @throws DOMException */ public Date put(TagTrkpt tag) throws DOMException, ParseException { this.put(tag.time, tag); return tag.time; } /** * 指定時刻(jptime)のTRKPTエレメントを取り出す。 * * @param jptime 指定する日時 * @return エレメントTRKPT。指定時刻に対応するノードがないときはnullを返す。 * @throws ParseException */ public TagTrkpt getValue(Date jptime) throws ParseException { TagTrkpt imaE = getTrkpt(jptime); if (imaE != null) { TagTrkpt maeE = getMaeTrkpt(imaE.time); if (maeE != null) { Complementation comp = new Complementation(imaE, maeE); // <MAGVAR>がなければ、 // 直前の位置と、現在地から進行方向を求める // 経度(longitude)と経度から進行方向を求める if (Complementation.param_GpxOverwriteMagvar) { comp.complementationMagvar(); } // 緯度・経度と時間差から速度(km/h)を求める if (Complementation.param_GpxOutputSpeed) { comp.complementationSpeed(); } //return (TagTrkpt)(comp.imaTag.trkpt.cloneNode(true)); return (TagTrkpt)(comp.imaTag); } return imaE; } return null; } /** * [map]から指定した時刻の<trkpt>エレメントを取り出す。 * 取り出すエレメントは、指定した時刻と同一時刻、もしくは、直近・直前の時刻のエレメントとする。 * 指定した時刻以前のエレメントが存在しない場合は null を返す。 * 指定した時刻と直近・直前のエレメントの時刻との乖離が プロパティ[OVER_TIME_LIMIT=3000(ミリ秒)]より大きい場合には null を返す。 * * @param jptime * @return <trkpt>エレメント。対象のエレメントが存在しなかった場合には null。 * @throws ParseException */ private TagTrkpt getTrkpt(Date jptime) throws ParseException { Date keyTime = null; for (Date key : this.keySet()) { int flag = jptime.compareTo(key); if (flag < 0) { if (keyTime != null) { return this.get(keyTime); } return null; } else if (flag == 0) { return this.get(key); } else if (flag > 0) { keyTime = new Date(key.getTime()); } } if (keyTime != null) { if (Math.abs(keyTime.getTime() - jptime.getTime()) <= OVER_TIME_LIMIT) { return this.get(keyTime); } } return null; } /** * ロガーの最終取得時刻を超えた場合、どこまでを有効とするかを設定する。 * この設定がないと、最終取得時刻を超えたものは全て有効になってしまう。 * OVER_TIME_LIMITは、GPSロガーの位置取得間隔()よりも長くする必要がある。長すぎても良くない。 */ public static long OVER_TIME_LIMIT = 3000; // ミリ秒(msec) private TagTrkpt getMaeTrkpt(Date time) throws ParseException { Date maeTime = null; for (Date key : this.keySet()) { int flag = time.compareTo(key); if (flag > 0) { maeTime = new Date(key.getTime()); } else if (flag == 0) { if (maeTime == null) { return null; } return this.get(maeTime); } else { // time は key より古い if (maeTime == null) { return null; } if (Math.abs(maeTime.getTime() - time.getTime()) > OVER_TIME_LIMIT) { return null; } return this.get(maeTime); } } return null; } public void printinfo() { Date firstTime = null; Date lastTime = null; for (Date key : this.keySet()) { if (firstTime == null) { firstTime = new Date(key.getTime()); } lastTime = new Date(key.getTime()); } System.out.println(String.format("| <trkseg/> |%20s|%20s|", ImportPicture.toUTCString(firstTime), ImportPicture.toUTCString(lastTime))); } }