*\r
* @param argv\r
* argv[-] = dummy\r
- * argv[0] = 画像ファイルが格納されているディレクトリ\r
- * argv[1] = 時刻補正の基準とする画像ファイル\r
- * argv[2] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd'T'HH:mm:ss"\r
- * argv[3] = [noEXIF] EXIF情報の書き換えを行わない / EXIF情報の書き換えを行う(出力先フォルダ)\r
- * argv[4] = 撮影位置をロギングしたGPXファイル\r
+ * argv[0] = 画像ファイルが格納されているディレクトリ --> imgDir\r
+ * argv[1] = 時刻補正の基準とする画像ファイル --> baseFile\r
+ * argv[2] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd'T'HH:mm:ss" --> timeStr\r
+ * argv[3] = 出力先フォルダ --> outDir\r
+ * argv[4] = 撮影位置をロギングしたGPXファイル --> gpxDir\r
* \r
* @throws IOException\r
* @throws ImageReadException \r
return;\r
}\r
\r
+ obj.params = new AppParameters();\r
+\r
+ // 基準時刻(ファイル更新日時 | EXIF撮影日時)\r
+ obj.exifBase = (obj.params.getProperty(AppParameters.GPX_BASETIME).equals("EXIF_TIME") ? true : false);\r
+\r
// 基準時刻ファイルの「更新日時」を使って時刻合わせを行う。\r
File baseFile = new File(obj.imgDir, argv[1]);\r
- jptime = new Date(baseFile.lastModified());\r
+ if (obj.exifBase) {\r
+ ImageMetadata meta = Imaging.getMetadata(baseFile);\r
+ JpegImageMetadata jpegMetadata = (JpegImageMetadata)meta;\r
+ if (jpegMetadata == null) {\r
+ System.out.println("'"+ baseFile.getAbsolutePath() +"' にEXIF情報がありません");\r
+ return;\r
+ }\r
+ TiffImageMetadata exif = jpegMetadata.getExif();\r
+ if (exif == null) {\r
+ System.out.println("'"+ baseFile.getAbsolutePath() +"' にEXIF情報がありません");\r
+ return;\r
+ }\r
+ String dateTimeOriginal = exif.getFieldValue(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL)[0];\r
+ long lastModifyTime = (new SimpleDateFormat("yyyy:MM:dd HH:mm:ss")).parse(dateTimeOriginal).getTime();\r
+ jptime = new Date(lastModifyTime);\r
+ }\r
+ else {\r
+ jptime = new Date(baseFile.lastModified());\r
+ }\r
+\r
String timeStr = argv[2];\r
try {\r
dfjp.setTimeZone(TimeZone.getTimeZone("JST"));\r
}\r
catch (ParseException e) {\r
System.out.println("'"+ timeStr +"' の書式が違います("+ TIME_FORMAT_STRING +")");\r
+ return;\r
}\r
\r
- // \r
- if (argv[3].toUpperCase().equals("noEXIF")) {\r
- obj.exif = false;\r
- obj.outDir = null;\r
- }\r
- else {\r
- obj.exif = true;\r
- obj.outDir = new File(argv[3]);\r
- }\r
+ // 出力ファイル\r
+ obj.outDir = new File(argv[3]);\r
\r
- // 第6引数が指定されなければ、指定されたディレクトリ内のGPXファイルすべてを対象とする\r
- if (argv.length >= 5) {\r
- obj.gpxDir = new File(argv[4]);\r
- }\r
+ // その他のパラメータを読み取る\r
+ String paramStr = obj.params.getProperty(AppParameters.GPX_GPXSPLIT);\r
+ if ((paramStr != null) && (paramStr.equals(Boolean.toString(true)))) {\r
+ obj.param_GpxSplit = true;\r
+ }\r
+ \r
+ paramStr = obj.params.getProperty(AppParameters.GPX_NO_FIRST_NODE);\r
+ if ((paramStr != null) && (paramStr.equals(Boolean.toString(true)))) {\r
+ obj.param_GpxNoFirstNode = true;\r
+ }\r
+ \r
+ paramStr = obj.params.getProperty(AppParameters.GPX_REUSE);\r
+ if ((paramStr != null) && (paramStr.equals(Boolean.toString(true)))) {\r
+ obj.param_GpxReuse = true;\r
+ }\r
+ \r
+ paramStr = obj.params.getProperty(AppParameters.GPX_OUTPUT_WPT);\r
+ if ((paramStr != null) && (paramStr.equals(Boolean.toString(true)))) {\r
+ obj.param_GpxOutputWpt = true;\r
+ }\r
+ \r
+ paramStr = obj.params.getProperty(AppParameters.GPX_OVERWRITE_MAGVAR);\r
+ if ((paramStr != null) && (paramStr.equals(Boolean.toString(true)))) {\r
+ Complementation.param_GpxOverwriteMagvar = true;\r
+ }\r
+\r
+ paramStr = obj.params.getProperty(AppParameters.GPX_OUTPUT_SPEED);\r
+ if ((paramStr != null) && (paramStr.equals(Boolean.toString(true)))) {\r
+ Complementation.param_GpxOutputSpeed = true;\r
+ }\r
+\r
+ paramStr = obj.params.getProperty(AppParameters.GPX_SOURCE_FOLDER);\r
+ if (paramStr != null) {\r
+ obj.param_GpxSourceFolder = new String(paramStr);\r
+ obj.gpxDir = new File(obj.param_GpxSourceFolder);\r
+ if (!obj.gpxDir.exists()) {\r
+ // GPXファイルまたはディレクトリが存在しません。\r
+ System.out.println("GPXファイルまたはディレクトリが存在しません。('"+ paramStr +"')");\r
+ return;\r
+ }\r
+ }\r
else {\r
obj.gpxDir = obj.imgDir;\r
}\r
- if (obj.gpxDir.isFile()) {\r
- obj.gpxFiles.add(new File(obj.gpxDir, argv[4])); \r
- }\r
- else {\r
+\r
+ // 指定されたディレクトリ内のGPXファイルすべてを対象とする\r
+ if (obj.gpxDir.isDirectory()) {\r
File[] files = obj.gpxDir.listFiles();\r
+ if (files == null) {\r
+ // 対象となるGPXファイルがありませんでした。\r
+ System.out.println("対象となるGPXファイルがありませんでした。('"+ obj.gpxDir.getAbsolutePath() +"')");\r
+ return;\r
+ }\r
for (File file : files) {\r
if (file.isFile()) {\r
String filename = file.getName().toUpperCase();\r
- if (filename.endsWith(".GPX")) {\r
- if (!filename.endsWith("_.GPX")) {\r
+ if (filename.toUpperCase().endsWith(".GPX")) {\r
+ if (!filename.toUpperCase().endsWith("_.GPX") || obj.param_GpxReuse) {\r
obj.gpxFiles.add(file);\r
}\r
}\r
}\r
}\r
}\r
- \r
+ else {\r
+ obj.gpxFiles.add(obj.gpxDir);\r
+ }\r
+\r
+ paramStr = obj.params.getProperty(AppParameters.IMG_OUTPUT_EXIF);\r
+ if ((paramStr != null) && (paramStr.equals(Boolean.toString(true)))) {\r
+ obj.exif = true;\r
+ }\r
+\r
+ System.out.println(" - param: imgDir = '"+ obj.imgDir.getAbsolutePath() +"'");\r
+ System.out.println(" - param: outDir = '"+ (obj.outDir == null ? "" : obj.outDir.getAbsolutePath()) +"'");\r
+ System.out.println(" - param: gpxDir = '"+ (obj.gpxDir == null ? "" : obj.gpxDir.getAbsolutePath()) +"'");\r
+ System.out.println(" - param: number of gpxFiles = '"+ obj.gpxFiles.size() +"'");\r
+ System.out.println(" - param: "+ AppParameters.GPX_GPXSPLIT +"="+ obj.param_GpxSplit);\r
+ System.out.println(" - param: "+ AppParameters.GPX_NO_FIRST_NODE +"="+ obj.param_GpxNoFirstNode); \r
+ System.out.println(" - param: "+ AppParameters.GPX_REUSE +"="+ obj.param_GpxReuse); \r
+ System.out.println(" - param: "+ AppParameters.GPX_BASETIME +"="+ obj.params.getProperty(AppParameters.GPX_BASETIME) );\r
+ System.out.println(" - param: "+ AppParameters.IMG_OUTPUT +"="+ obj.params.getProperty(AppParameters.IMG_OUTPUT)); \r
+ System.out.println(" - param: "+ AppParameters.IMG_OUTPUT_EXIF +"= "+ String.valueOf(obj.exif));\r
+ System.out.println(" - param: "+ AppParameters.GPX_SOURCE_FOLDER +"="+ obj.param_GpxSourceFolder);\r
+ System.out.println(" - param: "+ AppParameters.GPX_OUTPUT_WPT +"="+ obj.param_GpxOutputWpt);\r
+ System.out.println(" - param: "+ AppParameters.GPX_OVERWRITE_MAGVAR +"="+ Complementation.param_GpxOverwriteMagvar);\r
+ System.out.println(" - param: "+ AppParameters.GPX_OUTPUT_SPEED +"="+ Complementation.param_GpxOutputSpeed);\r
obj.start();\r
try {\r
obj.join(); \r
public File outDir;\r
public long delta = 0;\r
public boolean exif = false;\r
+ public boolean exifBase = false;\r
public ArrayList<File> gpxFiles = new ArrayList<>();\r
- \r
+ public AppParameters params;\r
+ public boolean param_GpxSplit = false;\r
+ public boolean param_GpxNoFirstNode = false;\r
+ public boolean param_GpxReuse = false;\r
+ //public boolean Complementation.param_GpxOutputSpeed = false;\r
+ //public boolean Complementation.param_GpxOverwriteMagvar = false;\r
+ public boolean param_GpxOutputWpt = true;\r
+ public String param_GpxSourceFolder = ".";\r
+ public static final long DIFF_MAE_TIME = 3000L; // before 3 secound\r
+ \r
@Override\r
public void run() {\r
- \r
/**\r
*\r
<wpt lat="35.25714922" lon="139.15490497">\r
<sat>9</sat>\r
</wpt>\r
*/\r
+ try {\r
+ if (params.getProperty(AppParameters.IMG_OUTPUT).equals(Boolean.toString(true))) {\r
+ outDir = new File(outDir, imgDir.getName());\r
+ }\r
+ else {\r
+ outDir = gpxDir;\r
+ }\r
+\r
+ for (File gpxFile : this.gpxFiles) {\r
+ procGPXfile(gpxFile);\r
+ }\r
+ }\r
+ catch(ParserConfigurationException | DOMException | SAXException | IOException | ParseException | ImageReadException | ImageWriteException | IllegalArgumentException | TransformerException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * 個別のGPXファイルを処理する\r
+ * \r
+ * @throws ParserConfigurationException \r
+ * @throws IOException \r
+ * @throws SAXException \r
+ * @throws ParseException \r
+ * @throws ImageWriteException \r
+ * @throws ImageReadException \r
+ * @throws TransformerException \r
+ */\r
+ void procGPXfile(File gpxFile) throws ParserConfigurationException, SAXException, IOException, ParseException, ImageReadException, ImageWriteException, TransformerException {\r
DocumentBuilderFactory factory;\r
DocumentBuilder builder;\r
Node gpx;\r
\r
- try {\r
- \r
- outDir = new File(outDir, imgDir.getName());\r
+ String fileName = gpxFile.getName();\r
+ String iStr = fileName.substring(0, fileName.length() - 4);\r
\r
- for (File gpxFile : this.gpxFiles) {\r
- String fileName = gpxFile.getName();\r
- String iStr = fileName.substring(0, fileName.length() - 4);\r
-\r
- File outputFile = new File(imgDir, iStr +"_.gpx");\r
- System.out.println(iStr + " => "+ outputFile.getName());\r
-\r
- factory = DocumentBuilderFactory.newInstance();\r
- builder = factory.newDocumentBuilder();\r
- factory.setIgnoringElementContentWhitespace(true);\r
- factory.setIgnoringComments(true);\r
- factory.setValidating(true);\r
-\r
- // GPX file --> Node root\r
- DOMImplementation domImpl = builder.getDOMImplementation();\r
- document = domImpl.createDocument("", "gpx", null);\r
-\r
- /*\r
- <gpx>\r
- <trk>\r
- <name><![CDATA[Tracked with OSMTracker for Android?]]></name>\r
- <cmt><![CDATA[警告: HDOP values aren't the HDOP as returned by the GPS device. They're approximated from the location accuracy in meters.]]></cmt>\r
- <trkseg>\r
- <trkpt lat="35.32123832" lon="139.56965631">\r
- <ele>47.20000076293945</ele>\r
- <time>2012-06-15T03:00:29Z</time>\r
- <hdop>0.5</hdop>\r
- </trkpt>\r
- </trkseg>\r
- </trk>\r
- <wpt lat="35.2564461" lon="139.15437809">\r
- </wpt>\r
- </gpx>\r
- */\r
- TreeMap<Long,Element> map = new TreeMap<>();\r
- Element trk = null;\r
- gpx = builder.parse(gpxFile).getFirstChild();\r
- NodeList nodes = gpx.getChildNodes();\r
- for (int i=0; i < nodes.getLength(); i++) {\r
- Node node2 = nodes.item(i);\r
- if (node2.getNodeName().equals("trk")) {\r
- trk = (Element) node2;\r
- trkptMap(trk, map);\r
- }\r
- }\r
+ File outputFile = new File(outDir, iStr +"_.gpx");\r
+ System.out.println(gpxFile.getAbsolutePath() + " => "+ outputFile.getAbsolutePath());\r
+ System.out.println(" 時差: "+ (delta / 1000) +"(sec)");\r
+ System.out.println(" Target GPX: ["+ gpxFile.getAbsolutePath() +"]");\r
+ System.out.println(" EXIF: "+ (exif ? ("convert to '" + outDir.getAbsolutePath() +"'") : "off"));\r
+ System.out.println();\r
\r
- boolean change = false;\r
- if (trk != null) {\r
- /*\r
- * GPXへ割りつける開始時刻と終了時刻を求める\r
- */\r
- long gpxStartTime = (new Date()).getTime(); // 対象とする開始時刻(現在時刻)\r
- long gpxEndTime = 0L; // 対象とする終了時刻\r
- Set<Long> keySet = map.keySet(); //すべてのキー値を取得\r
- for (Long timeLong : keySet) {\r
- long gpxTime = timeLong;\r
- if (gpxStartTime > gpxTime) {\r
- gpxStartTime = gpxTime;\r
- }\r
- if (gpxEndTime < gpxTime) {\r
- gpxEndTime = gpxTime;\r
+ factory = DocumentBuilderFactory.newInstance();\r
+ builder = factory.newDocumentBuilder();\r
+ factory.setIgnoringElementContentWhitespace(true);\r
+ factory.setIgnoringComments(true);\r
+ factory.setValidating(true);\r
+\r
+ // GPX file --> Node root\r
+ DOMImplementation domImpl = builder.getDOMImplementation();\r
+ document = domImpl.createDocument("", "gpx", null);\r
+\r
+ /*\r
+ * <gpx>\r
+ * <trk>\r
+ * <name><![CDATA[Tracked with OSMTracker for Android?]]></name>\r
+ * <cmt><![CDATA[警告: HDOP values aren't the HDOP as returned by the GPS device. They're approximated from the location accuracy in meters.]]></cmt>\r
+ * <trkseg>\r
+ * <trkpt lat="35.32123832" lon="139.56965631">\r
+ * <ele>47.20000076293945</ele>\r
+ * <time>2012-06-15T03:00:29Z</time>\r
+ * <hdop>0.5</hdop>\r
+ * </trkpt>\r
+ * </trkseg>\r
+ * </trk>\r
+ * <wpt lat="35.2564461" lon="139.15437809"></wpt>\r
+ * </gpx>\r
+ */\r
+ TreeMap<Long,Element> map = new TreeMap<Long, Element>();\r
+ TreeMap<Long,Element> mapTRKSEG = new TreeMap<>();\r
+ Element trk = null;\r
+ //Element maeTRKPT = null;\r
+ gpx = builder.parse(gpxFile).getFirstChild();\r
+ document = gpx.getOwnerDocument();\r
+ NodeList nodes = gpx.getChildNodes();\r
+ for (int i=0; i < nodes.getLength(); i++) {\r
+ Node node2 = nodes.item(i);\r
+ if (node2.getNodeName().equals("trk")) {\r
+ trk = (Element) node2;\r
+ \r
+ NodeList nodes1 = trk.getChildNodes();\r
+ int trksegCounter = 0;\r
+ for (int i1=0; i1 < nodes1.getLength(); i1++) {\r
+ Node nodeTRKSEG = nodes1.item(i1);\r
+ if (nodeTRKSEG.getNodeName().equals("trkseg")) {\r
+ trksegCounter++;\r
+ Element newTRKSEG = document.createElement("trkseg");\r
+ Element trkseg = (Element) nodeTRKSEG;\r
+ NodeList nodes2 = trkseg.getChildNodes();\r
+ for (int i2=0; i2 < nodes2.getLength(); i2++) {\r
+ Node nodeTRKPT = nodes2.item(i2);\r
+ if (nodeTRKPT.getNodeName().equals("trkpt")) {\r
+ if (param_GpxNoFirstNode && (i2 == 0)) {\r
+ continue;\r
+ }\r
+ newTRKSEG.appendChild(getCopy(document, nodeTRKPT));\r
+ }\r
}\r
- }\r
+ mapTRKSEG.put(new Long(trksegCounter), getCopy(document, newTRKSEG));\r
\r
- System.out.println(" 時差: "+ (delta / 1000) +"(sec)");\r
- System.out.println(" Target GPX: ["+ gpxFile.getAbsolutePath() +"]");\r
- System.out.println("GPX start time: "+ dfjp.format(new Date(gpxStartTime)) + "\t[GMT " + dfuk.format(new Date(gpxStartTime))+"]");\r
- System.out.println(" GPX end time: "+ dfjp.format(new Date(gpxEndTime)) + "\t[GMT " + dfuk.format(new Date(gpxEndTime))+"]");\r
- System.out.println(" EXIF: "+ (exif ? ("convert to '" + outDir.getAbsolutePath() +"'") : "off"));\r
- System.out.println();\r
- System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
- System.out.println(" name | UpdateTime | GPStime | Latitude | Longitude | ele |magvar|");\r
- System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
- change = proc(imgDir, delta, gpxStartTime, gpxEndTime, map, exif, gpx);\r
- System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
+ // <trk>から<trkseg>を削除する。\r
+ trk.removeChild(nodeTRKSEG);\r
+ }\r
}\r
+ \r
+ // <trkseg>毎に実行する\r
+ Iterator<Long> keyIte = mapTRKSEG.keySet().iterator();\r
+ while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得\r
\r
- // 出力\r
- if (change) {\r
- DOMSource source = new DOMSource(gpx);\r
- FileOutputStream os = new FileOutputStream(outputFile);\r
- StreamResult result = new StreamResult(os);\r
- TransformerFactory transFactory = TransformerFactory.newInstance();\r
- Transformer transformer = transFactory.newTransformer();\r
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
- transformer.setOutputProperty(OutputKeys.METHOD, "xml");\r
- transformer.transform(source, result); \r
- if (exif) {\r
- outputFile = new File(outDir, iStr +"_.gpx");\r
- os = new FileOutputStream(outputFile);\r
- result = new StreamResult(os);\r
- transformer.transform(source, result);\r
- }\r
+ // <trk>に、新たな<trkseg>を追加する。\r
+ Element newTRKSEG = mapTRKSEG.get(keyIte.next());\r
+ trk.appendChild(newTRKSEG);\r
+ \r
+ // mapに、<trkpt>を割り付ける\r
+ trkptMap(newTRKSEG, map);\r
}\r
}\r
}\r
- catch(ParserConfigurationException | DOMException | SAXException | IOException | ParseException | ImageReadException | ImageWriteException | IllegalArgumentException | TransformerException e) {\r
- }\r
+ \r
+ /*\r
+ * GPXへ割りつける開始時刻と終了時刻を求める\r
+ */\r
+ long gpxStartTime = (new Date()).getTime(); // 対象とする開始時刻(現在時刻)\r
+ long gpxEndTime = 0L; // 対象とする終了時刻\r
+ Set<Long> keySet = map.keySet(); //すべてのキー値を取得\r
+ for (Long timeLong : keySet) {\r
+ long gpxTime = timeLong;\r
+ if (gpxStartTime > gpxTime) {\r
+ gpxStartTime = gpxTime;\r
+ }\r
+ if (gpxEndTime < gpxTime) {\r
+ gpxEndTime = gpxTime;\r
+ }\r
+ }\r
+ \r
+ /*\r
+ * SPEEDをGPXに設定する\r
+ * 条件: SPEEDを書き出すフラグがONの時\r
+ * 条件: オリジナルのSPEEDがある場合「上書きする/変更しない」(GPX_OUTPUT_SPEED)\r
+ */\r
+ /*\r
+ TreeMap<Long,Element> map2 = new TreeMap<Long, Element>();\r
+ if (Boolean.parseBoolean(params.getProperty(AppParameters.GPX_OUTPUT_SPEED))) {\r
+ for (Long timeL : keySet) {\r
+ Element trkptE = trkpt(map, new Date(timeL));\r
+ if (trkptE != null) {\r
+ map2.put(timeL, trkptE);\r
+ }\r
+ else {\r
+ map2.put(timeL, map.get(timeL));\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ map2 = (TreeMap<Long, Element>) map.clone();\r
+ }\r
+ */\r
+ \r
+ System.out.println("GPX start time: "+ dfjp.format(new Date(gpxStartTime)) + "\t[GMT " + dfuk.format(new Date(gpxStartTime))+"]");\r
+ System.out.println(" GPX end time: "+ dfjp.format(new Date(gpxEndTime)) + "\t[GMT " + dfuk.format(new Date(gpxEndTime))+"]");\r
+ System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|------|");\r
+ System.out.println(" name | UpdateTime | GPStime | Latitude | Longitude | ele |magvar| km/h |");\r
+ System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|------|");\r
+ proc(imgDir, delta, gpxStartTime, gpxEndTime, map, exif, gpx);\r
+ System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|------|");\r
+\r
+ // 出力\r
+ DOMSource source = new DOMSource(gpx);\r
+ FileOutputStream os = new FileOutputStream(outputFile);\r
+ StreamResult result = new StreamResult(os);\r
+ TransformerFactory transFactory = TransformerFactory.newInstance();\r
+ Transformer transformer = transFactory.newTransformer();\r
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml");\r
+ transformer.transform(source, result); \r
+\r
+ outputFile = new File(outDir, iStr +"_.gpx");\r
+ os = new FileOutputStream(outputFile);\r
+ result = new StreamResult(os);\r
+ transformer.transform(source, result);\r
+\r
}\r
+ \r
\r
/**\r
* 再帰メソッド\r
DecimalFormat dayFormatter = new DecimalFormat("00");\r
\r
boolean ret = false;\r
- File[] files = dir.listFiles();\r
+ File[] files = dir.listFiles(new JpegFileFilter());\r
Arrays.sort(files, new FileSort());\r
for (File image : files) {\r
System.out.print(String.format("%12s|", image.getName()));\r
}\r
\r
Date itime = new Date(image.lastModified());\r
+ if (this.exifBase) {\r
+ ImageMetadata meta = Imaging.getMetadata(image);\r
+ JpegImageMetadata jpegMetadata = (JpegImageMetadata)meta;\r
+ if (jpegMetadata == null) {\r
+ System.out.println("'"+ image.getAbsolutePath() +"' にEXIF情報がありません");\r
+ continue;\r
+ }\r
+ TiffImageMetadata exif = jpegMetadata.getExif();\r
+ if (exif == null) {\r
+ System.out.println("'"+ image.getAbsolutePath() +"' にEXIF情報がありません");\r
+ continue;\r
+ }\r
+ String dateTimeOriginal = exif.getFieldValue(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL)[0];\r
+ long lastModifyTime = (new SimpleDateFormat("yyyy:MM:dd HH:mm:ss")).parse(dateTimeOriginal).getTime();\r
+ itime = new Date(lastModifyTime);\r
+ }\r
+\r
+ // uktime <-- 画像撮影時刻に対応するGPX時刻\r
Date uktime = new Date(itime.getTime() + delta);\r
System.out.print(String.format("%20s ", dfjp.format(itime)));\r
System.out.print(String.format("%20s|", dfjp.format(uktime)));\r
continue;\r
}\r
\r
- Element trkpt = trkpt(map, uktime);\r
- if (trkpt == null) {\r
+ // 時刻uktimeにおける<magver>をtrkptに追加する\r
+ Element trkptE = trkpt(map, uktime);\r
+ if (trkptE == null) {\r
System.out.println(String.format("%20s ", "Out of GPX logging time."));\r
continue;\r
}\r
- \r
- Element wpt = createWptTag(image, uktime.getTime(), trkpt);\r
- String latStr = wpt.getAttribute("lat");\r
- String lonStr = wpt.getAttribute("lon");\r
- double latitude = Double.parseDouble(latStr);\r
- double longitude = Double.parseDouble(lonStr);\r
+\r
+ TagTrkpt trkptT = new TagTrkpt(trkptE);\r
+\r
+ //Element wpt = createWptTag(image, uktime.getTime(), trkptE);\r
+ //String latStr = trkptT.lat.toString();\r
+ //String lonStr = trkptT.lon.toString();\r
+ double latitude = trkptT.lat;\r
+ double longitude = trkptT.lon;\r
\r
String eleStr = "-";\r
+ if (trkptT.eleStr != null) {\r
+ eleStr = new String(trkptT.eleStr);\r
+ }\r
+ \r
String magvarStr = "-";\r
- NodeList nodes = wpt.getChildNodes(); // 子ノードを取得\r
- for (int i4 = 0; i4 < nodes.getLength(); i4++) {\r
- Node node = nodes.item(i4);\r
- if (node != null) {\r
- switch (node.getNodeName()) {\r
- case "ele":\r
- eleStr = node.getFirstChild().getNodeValue();\r
- break;\r
- case "magvar":\r
- magvarStr = node.getFirstChild().getNodeValue();\r
- break;\r
- }\r
- }\r
+ if (trkptT.magvarStr != null) {\r
+ magvarStr = new String(trkptT.magvarStr);\r
+ }\r
+ \r
+ String speedStr = "-";\r
+ if (trkptT.speedStr != null) {\r
+ speedStr = new String(trkptT.speedStr);\r
}\r
\r
- System.out.print(String.format("%12s %12s|", latStr, lonStr));\r
- System.out.println(String.format("%8s|%6s|", eleStr, magvarStr));\r
+ System.out.print(String.format("%12s %12s|", (new Double(latitude)).toString(), (new Double(longitude)).toString()));\r
+ System.out.println(String.format("%8s|%6s|%6s|", eleStr, magvarStr, speedStr));\r
ret = true;\r
\r
if (exifWrite) {\r
}\r
}\r
\r
- Element temp = getCopy(gpx.getOwnerDocument(), wpt);\r
- gpx.appendChild(temp);\r
+ if (Boolean.parseBoolean(params.getProperty(AppParameters.GPX_OUTPUT_WPT))) {\r
+ Element temp = createWptTag(image, itime.getTime(), trkptT.trkpt);\r
+ gpx.appendChild(temp);\r
+ }\r
}\r
return ret;\r
}\r
/**\r
* XMLエレメント<trkpt>をTIMEでキー付したHashMapを生成する<br>\r
* \r
- * <trk><trkseg><trkpt><time>2014-01-01T00:59:09Z</time></trkpt></trkseg></trk>\r
+ * <trkseg>\r
+ * <trkpt lat="34.976635" lon="138.466228">\r
+ * <ele>267.291</ele>\r
+ * <magvar>359</magvar>\r
+ * <speed></speed>\r
+ * <time>2016-07-02T08:25:18Z</time>\r
+ * </trkpt>\r
+ * </trkseg>\r
* \r
* @param trk\r
* @param map\r
* @throws ParseException\r
*/\r
- public static void trkptMap(Element trk, TreeMap<Long,Element> map) throws ParseException {\r
+ public void trkptMap(Element trkseg, TreeMap<Long,Element> map) throws ParseException {\r
dfuk.setTimeZone(TimeZone.getTimeZone("GMT"));\r
\r
- NodeList nodes1 = trk.getChildNodes();\r
- for (int i1=0; i1 < nodes1.getLength(); i1++) {\r
- Node node2 = nodes1.item(i1);\r
- if (node2.getNodeName().equals("trkseg")) {\r
- Element trkseg = (Element) node2;\r
- NodeList nodes2 = trkseg.getChildNodes();\r
- for (int i2=0; i2 < nodes2.getLength(); i2++) {\r
- Node node3 = nodes2.item(i2);\r
- if (node3.getNodeName().equals("trkpt")) {\r
- Element trkpt = (Element) node3;\r
-\r
- NodeList nodes3 = trkpt.getChildNodes();\r
- for (int i3=0; i3 < nodes3.getLength(); i3++) {\r
- Node node4 = nodes3.item(i3);\r
- if (node4.getNodeName().equals("time")) {\r
- Element time = (Element) node4;\r
- NodeList nodes4 = time.getChildNodes(); // 子ノードを取得\r
- for (int i4=0; i4< nodes4.getLength(); i4++) {\r
- Node node5 = nodes4.item(i4);\r
- if (node5 != null) {\r
- if (node5.getNodeType() == Node.TEXT_NODE) {\r
- String timeStr = node5.getNodeValue();\r
- long t = dfuk.parse(timeStr).getTime();\r
- map.put(t, getCopy(trk.getOwnerDocument(), trkpt));\r
- }\r
- }\r
+ NodeList nodes2 = trkseg.getChildNodes();\r
+ for (int i2=0; i2 < nodes2.getLength(); i2++) {\r
+ Node node3 = nodes2.item(i2);\r
+ if (node3.getNodeName().equals("trkpt")) {\r
+ Element trkpt = (Element) node3;\r
+\r
+ NodeList nodes3 = trkpt.getChildNodes();\r
+ for (int i3=0; i3 < nodes3.getLength(); i3++) {\r
+ Node node4 = nodes3.item(i3);\r
+ if (node4.getNodeName().equals("time")) {\r
+ Element time = (Element) node4;\r
+ NodeList nodes4 = time.getChildNodes(); // 子ノードを取得\r
+ for (int i4=0; i4< nodes4.getLength(); i4++) {\r
+ Node node5 = nodes4.item(i4);\r
+ if (node5 != null) {\r
+ if (node5.getNodeType() == Node.TEXT_NODE) {\r
+ String timeStr = node5.getNodeValue();\r
+ long t = dfuk.parse(timeStr).getTime();\r
+ map.put(t, getCopy(trkseg.getOwnerDocument(), trkpt));\r
}\r
}\r
}\r
}\r
}\r
\r
+ \r
/**\r
* <trkpt lat="35.32123832" lon="139.56965631">\r
* <ele>47.20000076293945</ele>\r
* <time>2012-06-15T03:00:29Z</time>\r
* </trkpt>\r
+ *DIFF_MAE_TIME\r
* @return\r
* @param map\r
+ * @param jptime 画像ファイルの撮影日時 ミリ秒(日本時間)\r
+ * @throws ParseException\r
+ */\r
+ public Element trkpt(TreeMap<Long,Element> map, Date jptime) throws ParseException {\r
+ // 指定した時刻のエレメント(imaTrkpt)を取得する\r
+ Element imaE = getTrkpt(map, jptime);\r
+ if (imaE != null) {\r
+ Element maeE = getMaeTrkpt(map, new TagTrkpt(imaE));\r
+ if (maeE != null) {\r
+ Complementation comp = new Complementation(imaE, maeE);\r
+\r
+ // <MAGVAR>がなければ、\r
+ // 直前の位置と、現在地から進行方向を求める\r
+ // 経度(longitude)と経度から進行方向を求める\r
+ if (Complementation.param_GpxOverwriteMagvar) {\r
+ comp.complementationMagvar();\r
+ }\r
+\r
+ // 緯度・経度と時間差から速度(km/h)を求める\r
+ if (Complementation.param_GpxOutputSpeed) {\r
+ comp.complementationSpeed();\r
+ }\r
+ imaE = (Element)(comp.imaTag.trkpt.cloneNode(true));\r
+ }\r
+ }\r
+ return imaE;\r
+ }\r
+\r
+ /**\r
+ * [map]から指定した時刻の<trkpt>エレメントを取り出す。\r
+ * GPX時刻との差が10分以上は無効\r
+ * \r
+ * @param map\r
* @param jptime\r
+ * @return\r
* @throws ParseException\r
*/\r
- public static Element trkpt(TreeMap<Long,Element> map, Date jptime) throws ParseException {\r
- Double R = 20000000 / Math.PI;\r
+ public Element getTrkpt(TreeMap<Long,Element> map, Date jptime) throws ParseException {\r
long sa = 2L * 3600000L;\r
long jpt = jptime.getTime();\r
+ \r
Element ret = null;\r
- Element mae = null;\r
\r
Set<Long> keySet = map.keySet(); //すべてのキー値を取得\r
Iterator<Long> keyIte = keySet.iterator();\r
while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得\r
Long time = keyIte.next();\r
long t = time;\r
+\r
if (Math.abs(jpt - t) < sa) {\r
sa = Math.abs(jpt - t);\r
ret = map.get(time);\r
-\r
- // <MAGVAR>がなければ、\r
- // 直前の位置と、現在地から進行方向を求める\r
- NodeList nodes3 = ret.getChildNodes();\r
- Element magvar = null;\r
- for (int i3=0; i3 < nodes3.getLength(); i3++) {\r
- Node node4 = nodes3.item(i3);\r
- if (node4.getNodeName().toLowerCase().equals("magvar")) {\r
- magvar = (Element) node4;\r
- break;\r
- }\r
- }\r
- if (magvar == null) {\r
- if (mae != null) {\r
- Double maeLAT = null;\r
- Double maeLON = null;\r
- Double imaLAT = null;\r
- Double imaLON =null;\r
-\r
- // 経度(longitude)と経度から進行方向を求める\r
- NamedNodeMap nodeMap = mae.getAttributes();\r
- if (null != nodeMap) {\r
- for (int j=0; j < nodeMap.getLength(); j++ ) {\r
- switch (nodeMap.item(j).getNodeName()) {\r
- case "lat":\r
- String latStr = nodeMap.item(j).getNodeValue();\r
- maeLAT = new Double(latStr);\r
- break;\r
- case "lon":\r
- String lonStr = nodeMap.item(j).getNodeValue();\r
- maeLON = new Double(lonStr);\r
- break;\r
- }\r
- }\r
- nodeMap = ret.getAttributes();\r
- for (int j=0; j < nodeMap.getLength(); j++ ) {\r
- switch (nodeMap.item(j).getNodeName()) {\r
- case "lat":\r
- String latStr = nodeMap.item(j).getNodeValue();\r
- imaLAT = new Double(latStr);\r
- break;\r
- case "lon":\r
- String lonStr = nodeMap.item(j).getNodeValue();\r
- imaLON = new Double(lonStr);\r
- break;\r
- }\r
- }\r
- Double r = Math.cos(Math.toRadians((imaLAT + maeLAT) / 2)) * R;\r
- Double x = Math.toRadians(imaLON - maeLON) * r;\r
- Double y = Math.toRadians(imaLAT - maeLAT) * R;\r
- double rad = Math.toDegrees(Math.atan2(y, x));\r
- \r
- if (y >= 0) {\r
- if (x >= 0) {\r
- rad = 0 - (rad - 90);\r
- }\r
- else {\r
- rad = 360 - (rad - 90);\r
- }\r
- }\r
- else {\r
- if (x >= 0) {\r
- rad = 90 - rad;\r
- }\r
- else {\r
- rad = 90 - rad;\r
- }\r
- }\r
-\r
- magvar = ret.getOwnerDocument().createElement("magvar");\r
- String str = Double.toString(rad);\r
- int iDot = str.indexOf('.');\r
- if (iDot > 0) {\r
- str = str.substring(0, iDot);\r
- }\r
- magvar.setTextContent(str);\r
- ret.appendChild(magvar);\r
- \r
- Element speed = ret.getOwnerDocument().createElement("speed");\r
- str = Double.toString(Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));\r
- iDot = str.indexOf('.');\r
- if (iDot > 0) {\r
- str = str.substring(0, iDot);\r
- }\r
- speed.setTextContent(str);\r
- ret.appendChild(speed);\r
- }\r
- }\r
- }\r
}\r
- mae = map.get(time);\r
}\r
\r
if (sa < (60000L * 10L)) {\r
- // System.out.println(dfuk.format(jpt) +" ("+ sa +")");\r
+ // GPX時刻との差が10分以内なら有効\r
return ret;\r
}\r
return null;\r
}\r
\r
+ public Element getMaeTrkpt(TreeMap<Long,Element> map, TagTrkpt imaTrkpt) throws ParseException {\r
+ Element ret = null;\r
+ long diffTime = 2L * 3600000L; // 2時間\r
+ long jpt = imaTrkpt.time.getTime() - DIFF_MAE_TIME;\r
+\r
+ Set<Long> keySet = map.keySet(); //すべてのキー値を取得\r
+ Iterator<Long> keyIte = keySet.iterator();\r
+ while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得\r
+ Long time = keyIte.next();\r
+ long t = time;\r
+\r
+ if (Math.abs(jpt - t) < diffTime) {\r
+ diffTime = Math.abs(jpt - t);\r
+ ret = map.get(time);\r
+ }\r
+ }\r
+\r
+ if (diffTime < (60000L * 10L)) {\r
+ // GPX時刻との差が10分以内なら有効\r
+ if (diffTime < (imaTrkpt.time.getTime() - 1000)) {\r
+ // 元の時刻との差が1秒以上あること\r
+ return ret;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+ \r
/**\r
* 対象は '*.JPG' のみ対象とする\r
* @return \r
}\r
}\r
break;\r
+ case "speed":\r
+ for (int i2=0; i2 < nodes2.getLength(); i2++) {\r
+ Node node2 = nodes2.item(i2);\r
+ if (node2 != null) {\r
+ if (node2.getNodeType() == Node.TEXT_NODE) {\r
+ String speedStr = node2.getNodeValue();\r
+ Element speedE = document.createElement("speed");\r
+ speedE.setTextContent(speedStr);\r
+ wpt.appendChild(speedE);\r
+ }\r
+ }\r
+ }\r
+ break;\r
}\r
}\r
\r
}\r
}\r
\r
+ /**\r
+ * JPEGファイルフィルター\r
+ * @author yuu\r
+ */\r
+ class JpegFileFilter implements FilenameFilter{\r
+ public boolean accept(File dir, String name) {\r
+ if (name.toUpperCase().matches(".*\\.JPG$")) {\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+ }\r
}
\ No newline at end of file