OSDN Git Service

直近のtrkpt からmagver(進行方向) を算出。ただし、exifへは未反映
authorhayashi yuu <hayashi.yuu@gmail.com>
Sun, 26 Jul 2015 00:25:58 +0000 (09:25 +0900)
committerhayashi yuu <hayashi.yuu@gmail.com>
Sun, 26 Jul 2015 00:25:58 +0000 (09:25 +0900)
refacterring

importPicture/src/osm/jp/gpx/ImportPicture.java

index f4d2ea8..a5601c6 100644 (file)
@@ -19,8 +19,6 @@ import java.util.logging.Logger;
 import javax.xml.parsers.*;\r
 import javax.xml.transform.OutputKeys;\r
 import javax.xml.transform.Transformer;\r
-import javax.xml.transform.TransformerConfigurationException;\r
-import javax.xml.transform.TransformerException;\r
 import javax.xml.transform.TransformerFactory;\r
 import javax.xml.transform.dom.DOMSource;\r
 import javax.xml.transform.stream.StreamResult;\r
@@ -38,7 +36,6 @@ import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants;
 import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;\r
 import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;\r
 import org.w3c.dom.*;\r
-import org.xml.sax.SAXException;\r
 \r
 public class ImportPicture {\r
        public static File gpxDir = new File(".");\r
@@ -83,693 +80,680 @@ public class ImportPicture {
         }\r
     }\r
 \r
-       /** メイン\r
-        * 画像ファイルをGPXファイルに取り込みます。\r
-        * \r
-        * ・画像ファイルの更新日付をその画像の撮影日時とします。(Exi情報は無視します)\r
-        *    ※ 対象とするファイルは'*.jpg'のみ\r
-        * ・精確な時刻との時差を入力することで、撮影日時を補正します。\r
-        * ・画像ファイルの更新日付リストをCSV形式のファイルとして出力する。\r
-        * ・・結果は、取り込み元のGPXファイルとは別に、元ファイル名にアンダーバー「_」を付加した.ファイルに出力します。\r
-        *\r
-        * argv[-] = dummy\r
-        * argv[0] = 画像ファイルが格納されているディレクトリ\r
-        * argv[1] = 時刻補正の基準とする画像ファイル\r
-        * argv[2] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd'T'HH:mm:ss"\r
-        * argv[3] = [EXIF] EXIF情報の書き換えを行う / [not] EXIF情報の書き換えを行わない\r
-        * argv[4] = 撮影位置をロギングしたGPXファイル\r
-        * \r
-        * @throws IOException\r
-        * @throws ImageReadException \r
-        */\r
-       public static void main(String[] argv) throws Exception\r
-       {\r
-               Date jptime;\r
-               \r
-               if (argv.length > 0) {\r
-                       gpxDir = new File(argv[0]);\r
-               }\r
-\r
-               if (argv.length < 4) {\r
-                       System.out.println("!!! Illigal command call. !!!");\r
-                       System.out.println("> java -cp .:AdjustTime.jar:commons-imaging-1.0-SNAPSHOT.jar <targetDir> <time base image> <time> {EXIF/not} (gpx)");\r
-                       System.out.println("> java -cp .:AdjustTime.jar:commons-imaging-1.0-SNAPSHOT.jar. IMG_01234.JPG 2012-06-15T12:52:22 EXIF");\r
-                       System.out.println("> java -cp .:AdjustTime.jar . IMG_01234.JPG 2012-06-15T12:52:22 not");\r
-                       System.out.println();\r
-                       return;\r
-               }\r
-\r
-               // 基準時刻ファイルの「更新日時」を使って時刻合わせを行う。\r
-               File baseFile = new File(gpxDir, argv[1]);\r
-               jptime = new Date(baseFile.lastModified());\r
-               \r
-               // \r
-               boolean exif = false;\r
-               if (argv[3].toUpperCase().equals("EXIF")) {\r
-                       exif = true;\r
-               }\r
-               \r
-               // 第6引数が指定されなければ、指定されたディレクトリ内のGPXファイルすべてを対象とする\r
-               ArrayList<File> gpxFiles = new ArrayList<File>();\r
-               if (argv.length > 4) {\r
-                       gpxFiles.add(new File(gpxDir, argv[4]));\r
-               }\r
-               else {\r
-                       File[] files = gpxDir.listFiles();\r
-                       for (int i=0; i < files.length; i++) {\r
-                               if (files[i].isFile()) {\r
-                                       String filename = files[i].getName().toUpperCase();\r
-                                       if (filename.endsWith(".GPX")) {\r
-                                               if (!filename.endsWith("_.GPX")) {\r
-                                                       gpxFiles.add(files[i]);\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-\r
-               \r
-               /**\r
-                *\r
-                       <wpt lat="35.25714922" lon="139.15490497">\r
-                               <ele>62.099998474121094</ele>\r
-                               <time>2012-06-11T00:44:38Z</time>\r
-                               <hdop>0.75</hdop>\r
-                               <name><![CDATA[写真]]></name>\r
-                               <cmt><![CDATA[精度: 3.0m]]></cmt>\r
-                               <link href="2012-06-11_09-44-38.jpg">\r
-                                       <text>2012-06-11_09-44-38.jpg</text>\r
-                               </link>\r
-                               <sat>9</sat>\r
-                       </wpt>\r
-                */\r
-               DocumentBuilderFactory factory;\r
-               DocumentBuilder        builder;\r
-               Node gpx;\r
-               \r
-               try {\r
-                       for (int gpxCnt = 0; gpxCnt < gpxFiles.size(); gpxCnt++) {\r
-                               File gpxFile = gpxFiles.get(gpxCnt);\r
-                               String fileName = gpxFile.getName();\r
-                               String iStr = fileName.substring(0, fileName.length() - 4);\r
-       \r
-                               File outputFile = new File(gpxFile.getParent(), 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
-                               HashMap<Long,Element> map = new HashMap<Long,Element>();\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
-\r
-                               if (trk != null) {\r
-                                       dfjp.setTimeZone(TimeZone.getTimeZone("JST"));\r
-                                       String timeStr = argv[2];\r
-                                       try {\r
-                                               Date t = dfjp.parse(timeStr);\r
-                                               long delta = t.getTime() - jptime.getTime();\r
-                                               \r
-                                               /*\r
-                                                * GPXへ割りつける開始時刻と終了時刻を求める\r
-                                                */\r
-                                               long gpxStartTime = (new Date()).getTime();             // 対象とする開始時刻(現在時刻)\r
-                                               long gpxEndTime = 0L;                                                   // 対象とする終了時刻\r
-                                               Set<Long> keySet = map.keySet();  //すべてのキー値を取得\r
-                                               for (Iterator<Long> keyIte = keySet.iterator(); keyIte.hasNext();) {\r
-                                                       Long timeLong = (Long)keyIte.next();\r
-                                                       long gpxTime = timeLong.longValue();\r
-                                                       if (gpxStartTime > gpxTime) {\r
-                                                               gpxStartTime = gpxTime;\r
-                                                       }\r
-                                                       if (gpxEndTime < gpxTime) {\r
-                                                               gpxEndTime = gpxTime;\r
-                                                       }\r
-                                               }\r
-                                               \r
-                                               System.out.println("           時差: "+ (delta / 1000) +"(sec)");\r
-                                               System.out.println("    Target GPX: ["+ gpxFile.getName() +"]");\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("------------|--------------------|--------------------|------------|------------|--------|------|");\r
-                                               System.out.println(" name       | UpdateTime         | GPStime            | Latitude   | Longitude  | ele    |magvar|");\r
-                                               System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
-                                               proc(gpxDir, delta, gpxStartTime, gpxEndTime, map, exif, gpx);\r
-                                               System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
-                                       }\r
-                                       catch (ParseException e) {\r
-                                               System.out.println("'"+ timeStr +"' の書式が違います("+ TIME_FORMAT_STRING +")");\r
-                                       }\r
-                               }\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
-               }\r
-               catch (ParserConfigurationException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               catch (SAXException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               catch (TransformerConfigurationException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               catch (TransformerException e) {\r
-                       e.printStackTrace();\r
-               } catch (ParseException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               finally {\r
-               }\r
-       }\r
-       \r
-       /**\r
-        * 再帰メソッド\r
-        * @throws ParseException \r
-        * @throws IOException \r
-        * @throws ImageReadException \r
-        * @throws ImageWriteException \r
-        */\r
-       static void proc(File dir, long delta, long gpxStartTime, long gpxEndTime, HashMap<Long,Element> map, boolean exifWrite, Node gpx) throws ParseException, ImageReadException, IOException, ImageWriteException {\r
-               DecimalFormat yearFormatter = new DecimalFormat("0000");\r
-               DecimalFormat monthFormatter = new DecimalFormat("00");\r
-               DecimalFormat dayFormatter = new DecimalFormat("00");\r
-               \r
-               File[] files = dir.listFiles();\r
-               Arrays.sort(files, new FileSort());\r
-               for (File image : files) {\r
-                       if (image.isDirectory()) {\r
-                               proc(image, delta, gpxStartTime, gpxEndTime, map, exifWrite, gpx);\r
-                       }\r
-                       else {\r
-                               String imageName = image.getName();\r
-                               if (checkFile(imageName)) {\r
-                                       Date itime = new Date(image.lastModified());\r
-                                       Date uktime = new Date(itime.getTime() + delta);\r
-                                       if ((uktime.getTime() >= gpxStartTime) && (uktime.getTime() <= gpxEndTime)) {\r
-                                               Element trkpt = trkpt(map, uktime);\r
-                                               if (trkpt != null) {\r
-                                                       System.out.print(String.format("%12s|", image.getName()));\r
-                                                       System.out.print(String.format("%20s ", dfjp.format(itime)));\r
-                                                       System.out.print(String.format("%20s|", dfjp.format(uktime)));\r
-\r
-                                                       Element wpt = createWptTag(image, uktime.getTime(), trkpt);\r
-                                                       String latStr = wpt.getAttribute("lat");\r
-                                                       String lonStr = wpt.getAttribute("lon");\r
-                                                       System.out.print(String.format("%12s %12s|", latStr, lonStr));\r
-                                                       double latitude = Double.parseDouble(latStr);\r
-                                                       double longitude = Double.parseDouble(lonStr);\r
-                                                       \r
-                                                       String eleStr = null;\r
-                                                        String magvarStr = null;\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
-                                                                       if (node.getNodeName().equals("ele")) {\r
-                                                                               eleStr = node.getFirstChild().getNodeValue();\r
-                                                                               System.out.println(String.format("%8s|", eleStr));\r
-                                                                               break;\r
-                                                                       }\r
-                                                                       if (node.getNodeName().equals("magvar")) {\r
-                                                                               magvarStr = node.getFirstChild().getNodeValue();\r
-                                                                               System.out.println(String.format("%6s|", magvarStr));\r
-                                                                               break;\r
-                                                                       }\r
-                                                                }\r
-                                                               else {\r
-                                                                       System.out.println("-");\r
-                                                                       break;\r
-                                                               }\r
-                                                       }\r
-                                                       \r
-                                                       if (exifWrite) {\r
-                                                               TiffOutputSet outputSet = null;\r
-                                                               FileOutputStream fos = null;\r
-                                                               \r
-                                                               ImageMetadata meta = Imaging.getMetadata(image);\r
-                                                               JpegImageMetadata jpegMetadata = (JpegImageMetadata)meta;\r
-                                                               if (jpegMetadata != null) {\r
-                                                                       TiffImageMetadata exif = jpegMetadata.getExif();\r
-                                                                       if (exif != null) {\r
-                                                                               outputSet = exif.getOutputSet();\r
-                                                                       }\r
-                                                               }\r
-                                                               \r
-                                                               if (outputSet == null) {\r
-                                                                       System.out.println("added : new tiff output set");\r
-                                                                       outputSet = new TiffOutputSet();\r
-                                                               }\r
-                                                               \r
-                                                               //---- EXIF_TAG_DATE_TIME_ORIGINAL / 「撮影日時/オリジナル画像の生成日時」----\r
-                                                               TiffOutputDirectory exifDir = outputSet.getOrCreateExifDirectory();\r
-                                                               {\r
-                                                                       Calendar cal = GregorianCalendar.getInstance();\r
-                                                                       cal.setTime(uktime);\r
-                                                                       exifDir.removeField(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);\r
-                                                                       exifDir.add(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL, new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").format(cal.getTime()));\r
-                                                               }\r
-                                                               \r
-                                                               //---- EXIF GPS_TIME_STAMP ----\r
-                                                               TiffOutputDirectory gpsDir = outputSet.getOrCreateGPSDirectory();\r
-                                                               {\r
-                                                                       Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));\r
-                                                                       cal.setTime(uktime);\r
-                                                                       final String yearStr = yearFormatter.format(cal.get(Calendar.YEAR));\r
-                                                                       final String monthStr = monthFormatter.format(cal.get(Calendar.MONTH) + 1);\r
-                                                                       final String dayStr = dayFormatter.format(cal.get(Calendar.DAY_OF_MONTH));\r
-                                                                       final String dateStamp = yearStr +":"+ monthStr +":"+ dayStr;\r
-                                                                       \r
-                                                                       gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP);\r
-                                                                       gpsDir.add(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP,\r
-                                                                                       RationalNumber.valueOf(cal.get(Calendar.HOUR_OF_DAY)),\r
-                                                                                       RationalNumber.valueOf(cal.get(Calendar.MINUTE)),\r
-                                                                                       RationalNumber.valueOf(cal.get(Calendar.SECOND)));\r
-                                                                       gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_DATE_STAMP);\r
-                                                                       gpsDir.add(GpsTagConstants.GPS_TAG_GPS_DATE_STAMP, dateStamp);\r
-                                                               }\r
-                                                               \r
-                                                               //---- EXIF GPS elevation/ALTITUDE ----\r
-                                                               if (eleStr != null) {\r
-                                                                       final double altitude = Double.parseDouble(eleStr);\r
-                                                                       gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_ALTITUDE);\r
-                                                                       gpsDir.add(GpsTagConstants.GPS_TAG_GPS_ALTITUDE, RationalNumber.valueOf(altitude));\r
-                                                               }\r
-                                                               \r
-                                                               //---- EXIF GPS_ ----\r
-                                                               final String longitudeRef = (longitude < 0 ? "W" : "E");\r
-                                                               longitude = Math.abs(longitude);\r
-                                                               final String latitudeRef = (latitude < 0 ? "S" : "N");\r
-                                                               latitude = Math.abs(latitude);\r
-                                                               \r
-                                                               gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);\r
-                                                               gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF, longitudeRef);\r
-                                                               gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);\r
-                                                               gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF, latitudeRef);\r
-                                                                {\r
-                                                                        double value = longitude;\r
-                                                                        final double longitudeDegrees = (long) value;\r
-                                                                        value %= 1;\r
-                                                                        value *= 60.0;\r
-                                                                        final double longitudeMinutes = (long) value;\r
-                                                                        value %= 1;\r
-                                                                        value *= 60.0;\r
-                                                                        final double longitudeSeconds = value;\r
-                                                                        gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LONGITUDE);\r
-                                                                        gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LONGITUDE,\r
-                                                                                        RationalNumber.valueOf(longitudeDegrees),\r
-                                                                                        RationalNumber.valueOf(longitudeMinutes),\r
-                                                                                        RationalNumber.valueOf(longitudeSeconds));\r
-                                                                }\r
-                                                                {\r
-                                                                        double value = latitude;\r
-                                                                        final double latitudeDegrees = (long) value;\r
-                                                                        value %= 1;\r
-                                                                        value *= 60.0;\r
-                                                                        final double latitudeMinutes = (long) value;\r
-                                                                        value %= 1;\r
-                                                                        value *= 60.0;\r
-                                                                        final double latitudeSeconds = value;\r
-                                                                        gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LATITUDE);\r
-                                                                        gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LATITUDE,\r
-                                                                                        RationalNumber.valueOf(latitudeDegrees),\r
-                                                                                        RationalNumber.valueOf(latitudeMinutes),\r
-                                                                                        RationalNumber.valueOf(latitudeSeconds));\r
-                                                                }\r
-                                                               \r
-                                                               ExifRewriter rewriter = new ExifRewriter();\r
-                                                               try {\r
-                                                                       if (outDir == null) {\r
-                                                                               outDir = new File(dir, "converted");\r
-                                                                               outDir.mkdir();\r
-                                                                       }\r
-                                                                       fos = new FileOutputStream(new File(outDir, imageName));\r
-                                                                       rewriter.updateExifMetadataLossy(image, fos, outputSet);\r
-                                                               }\r
-                                                               finally {\r
-                                                                       if (fos != null) {\r
-                                                                               fos.close();\r
-                                                                       }\r
-                                                               }\r
-                                                       }\r
-\r
-                                                       Element temp = getCopy(gpx.getOwnerDocument(), wpt);\r
-                                                       gpx.appendChild(temp);\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       \r
-       static Document document;\r
+    /** メイン\r
+     * 画像ファイルをGPXファイルに取り込みます。\r
+     * \r
+     * ・画像ファイルの更新日付をその画像の撮影日時とします。(Exi情報は無視します)\r
+     *    ※ 対象とするファイルは'*.jpg'のみ\r
+     * ・精確な時刻との時差を入力することで、撮影日時を補正します。\r
+     * ・画像ファイルの更新日付リストをCSV形式のファイルとして出力する。\r
+     * ・・結果は、取り込み元のGPXファイルとは別に、元ファイル名にアンダーバー「_」を付加した.ファイルに出力します。\r
+     *\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] = [EXIF] EXIF情報の書き換えを行う / [not] EXIF情報の書き換えを行わない\r
+     * argv[4] = 撮影位置をロギングしたGPXファイル\r
+     * \r
+     * @throws IOException\r
+     * @throws ImageReadException \r
+     */\r
+    public static void main(String[] argv) throws Exception\r
+    {\r
+        Date jptime;\r
+\r
+        if (argv.length > 0) {\r
+            gpxDir = new File(argv[0]);\r
+        }\r
 \r
-       /**\r
-        * 2012-06-10T05:09:46Z  (日本時間の'2012-06-10T14:09:46')\r
-        */\r
-       public static final String TIME_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ss";\r
-       public static SimpleDateFormat dfjp = new SimpleDateFormat(TIME_FORMAT_STRING);\r
-       public static SimpleDateFormat dfuk = new SimpleDateFormat(TIME_FORMAT_STRING +"'Z'");\r
+        if (argv.length < 4) {\r
+            System.out.println("!!! Illigal command call. !!!");\r
+            System.out.println("> java -cp .:AdjustTime.jar:commons-imaging-1.0-SNAPSHOT.jar <targetDir> <time base image> <time> {EXIF/not} (gpx)");\r
+            System.out.println("> java -cp .:AdjustTime.jar:commons-imaging-1.0-SNAPSHOT.jar. IMG_01234.JPG 2012-06-15T12:52:22 EXIF");\r
+            System.out.println("> java -cp .:AdjustTime.jar . IMG_01234.JPG 2012-06-15T12:52:22 not");\r
+            System.out.println();\r
+            return;\r
+        }\r
+\r
+        // 基準時刻ファイルの「更新日時」を使って時刻合わせを行う。\r
+        File baseFile = new File(gpxDir, argv[1]);\r
+        jptime = new Date(baseFile.lastModified());\r
+\r
+        // \r
+        boolean exif = false;\r
+        if (argv[3].toUpperCase().equals("EXIF")) {\r
+            exif = true;\r
+        }\r
+\r
+        // 第6引数が指定されなければ、指定されたディレクトリ内のGPXファイルすべてを対象とする\r
+        ArrayList<File> gpxFiles = new ArrayList<>();\r
+        if (argv.length > 4) {\r
+            gpxFiles.add(new File(gpxDir, argv[4]));\r
+        }\r
+        else {\r
+            File[] files = gpxDir.listFiles();\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
+                            gpxFiles.add(file);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
 \r
-       /**\r
-        * XMLエレメント<trkpt>をTIMEでキー付したHashMapを生成する<br>\r
-        * \r
-        *      <trk><trkseg><trkpt><time>2014-01-01T00:59:09Z</time></trkpt></trkseg></trk>\r
-        * \r
-        * @param trk\r
-        * @return\r
-        * @throws ParseException\r
-        */\r
-       public static void trkptMap(Element trk, HashMap<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(new Long(t), getCopy(trk.getOwnerDocument(), trkpt));\r
-                                                                               }\r
-                                                                   }\r
-                                                               }\r
-                                                       }\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
-        */\r
-       public static Element trkpt(HashMap<Long,Element> map, Date jptime) throws ParseException {\r
-            Double R = 20000000 / Math.PI;                  // 地球の半径(m)\r
-            long sa = 2L * 3600000L;\r
-            long jpt = jptime.getTime();\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
-                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
+                <wpt lat="35.25714922" lon="139.15490497">\r
+                        <ele>62.099998474121094</ele>\r
+                        <time>2012-06-11T00:44:38Z</time>\r
+                        <hdop>0.75</hdop>\r
+                        <name><![CDATA[写真]]></name>\r
+                        <cmt><![CDATA[精度: 3.0m]]></cmt>\r
+                        <link href="2012-06-11_09-44-38.jpg">\r
+                                <text>2012-06-11_09-44-38.jpg</text>\r
+                        </link>\r
+                        <sat>9</sat>\r
+                </wpt>\r
+         */\r
+        DocumentBuilderFactory factory;\r
+        DocumentBuilder        builder;\r
+        Node gpx;\r
+\r
+        for (File gpxFile : gpxFiles) {\r
+            String fileName = gpxFile.getName();\r
+            String iStr = fileName.substring(0, fileName.length() - 4);\r
+\r
+            File outputFile = new File(gpxFile.getParent(), 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
+            HashMap<Long,Element> map = new HashMap<>();\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
+\r
+            if (trk != null) {\r
+                dfjp.setTimeZone(TimeZone.getTimeZone("JST"));\r
+                String timeStr = argv[2];\r
+                try {\r
+                    Date t = dfjp.parse(timeStr);\r
+                    long delta = t.getTime() - jptime.getTime();\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
-                    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
+                    System.out.println("           時差: "+ (delta / 1000) +"(sec)");\r
+                    System.out.println("    Target GPX: ["+ gpxFile.getName() +"]");\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("------------|--------------------|--------------------|------------|------------|--------|------|");\r
+                    System.out.println(" name       | UpdateTime         | GPStime            | Latitude   | Longitude  | ele    |magvar|");\r
+                    System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
+                    proc(gpxDir, delta, gpxStartTime, gpxEndTime, map, exif, gpx);\r
+                    System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
+                }\r
+                catch (ParseException e) {\r
+                    System.out.println("'"+ timeStr +"' の書式が違います("+ TIME_FORMAT_STRING +")");\r
+                }\r
+            }\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
+    }\r
+       \r
+    /**\r
+     * 再帰メソッド\r
+     * @throws ParseException \r
+     * @throws IOException \r
+     * @throws ImageReadException \r
+     * @throws ImageWriteException \r
+     */\r
+    static void proc(File dir, long delta, long gpxStartTime, long gpxEndTime, HashMap<Long,Element> map, boolean exifWrite, Node gpx) throws ParseException, ImageReadException, IOException, ImageWriteException {\r
+        DecimalFormat yearFormatter = new DecimalFormat("0000");\r
+        DecimalFormat monthFormatter = new DecimalFormat("00");\r
+        DecimalFormat dayFormatter = new DecimalFormat("00");\r
+\r
+        File[] files = dir.listFiles();\r
+        Arrays.sort(files, new FileSort());\r
+        for (File image : files) {\r
+            if (image.isDirectory()) {\r
+                proc(image, delta, gpxStartTime, gpxEndTime, map, exifWrite, gpx);\r
+            }\r
+            else {\r
+                String imageName = image.getName();\r
+                if (checkFile(imageName)) {\r
+                    Date itime = new Date(image.lastModified());\r
+                    Date uktime = new Date(itime.getTime() + delta);\r
+                    if ((uktime.getTime() >= gpxStartTime) && (uktime.getTime() <= gpxEndTime)) {\r
+                        Element trkpt = trkpt(map, uktime);\r
+                        if (trkpt != null) {\r
+                            System.out.print(String.format("%12s|", image.getName()));\r
+                            System.out.print(String.format("%20s ", dfjp.format(itime)));\r
+                            System.out.print(String.format("%20s|", dfjp.format(uktime)));\r
+\r
+                            Element wpt = createWptTag(image, uktime.getTime(), trkpt);\r
+                            String latStr = wpt.getAttribute("lat");\r
+                            String lonStr = wpt.getAttribute("lon");\r
+                            System.out.print(String.format("%12s %12s|", latStr, lonStr));\r
+                            double latitude = Double.parseDouble(latStr);\r
+                            double longitude = Double.parseDouble(lonStr);\r
+\r
+                            String eleStr = null;\r
+                            String magvarStr = null;\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
+                                    if (node.getNodeName().equals("ele")) {\r
+                                        eleStr = node.getFirstChild().getNodeValue();\r
+                                        System.out.println(String.format("%8s|", eleStr));\r
+                                        break;\r
+                                    }\r
+                                    if (node.getNodeName().equals("magvar")) {\r
+                                        magvarStr = node.getFirstChild().getNodeValue();\r
+                                        System.out.println(String.format("%6s|", magvarStr));\r
+                                        break;\r
+                                    }\r
+                                }\r
+                                else {\r
+                                    System.out.println("-");\r
+                                    break;\r
+                                }\r
+                            }\r
+\r
+                            if (exifWrite) {\r
+                                TiffOutputSet outputSet = null;\r
+                                FileOutputStream fos = null;\r
+\r
+                                ImageMetadata meta = Imaging.getMetadata(image);\r
+                                JpegImageMetadata jpegMetadata = (JpegImageMetadata)meta;\r
+                                if (jpegMetadata != null) {\r
+                                    TiffImageMetadata exif = jpegMetadata.getExif();\r
+                                    if (exif != null) {\r
+                                        outputSet = exif.getOutputSet();\r
+                                    }\r
+                                }\r
+\r
+                                if (outputSet == null) {\r
+                                    System.out.println("added : new tiff output set");\r
+                                    outputSet = new TiffOutputSet();\r
+                                }\r
+\r
+                                //---- EXIF_TAG_DATE_TIME_ORIGINAL / 「撮影日時/オリジナル画像の生成日時」----\r
+                                TiffOutputDirectory exifDir = outputSet.getOrCreateExifDirectory();\r
+                                {\r
+                                    Calendar cal = GregorianCalendar.getInstance();\r
+                                    cal.setTime(uktime);\r
+                                    exifDir.removeField(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);\r
+                                    exifDir.add(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL, new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").format(cal.getTime()));\r
+                                }\r
+\r
+                                //---- EXIF GPS_TIME_STAMP ----\r
+                                TiffOutputDirectory gpsDir = outputSet.getOrCreateGPSDirectory();\r
+                                {\r
+                                    Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));\r
+                                    cal.setTime(uktime);\r
+                                    final String yearStr = yearFormatter.format(cal.get(Calendar.YEAR));\r
+                                    final String monthStr = monthFormatter.format(cal.get(Calendar.MONTH) + 1);\r
+                                    final String dayStr = dayFormatter.format(cal.get(Calendar.DAY_OF_MONTH));\r
+                                    final String dateStamp = yearStr +":"+ monthStr +":"+ dayStr;\r
+\r
+                                    gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP);\r
+                                    gpsDir.add(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP,\r
+                                            RationalNumber.valueOf(cal.get(Calendar.HOUR_OF_DAY)),\r
+                                            RationalNumber.valueOf(cal.get(Calendar.MINUTE)),\r
+                                            RationalNumber.valueOf(cal.get(Calendar.SECOND)));\r
+                                    gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_DATE_STAMP);\r
+                                    gpsDir.add(GpsTagConstants.GPS_TAG_GPS_DATE_STAMP, dateStamp);\r
+                                }\r
+\r
+                                //---- EXIF GPS elevation/ALTITUDE ----\r
+                                if (eleStr != null) {\r
+                                    final double altitude = Double.parseDouble(eleStr);\r
+                                    gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_ALTITUDE);\r
+                                    gpsDir.add(GpsTagConstants.GPS_TAG_GPS_ALTITUDE, RationalNumber.valueOf(altitude));\r
+                                }\r
+\r
+                                //---- EXIF GPS_ ----\r
+                                final String longitudeRef = (longitude < 0 ? "W" : "E");\r
+                                longitude = Math.abs(longitude);\r
+                                final String latitudeRef = (latitude < 0 ? "S" : "N");\r
+                                latitude = Math.abs(latitude);\r
+\r
+                                gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);\r
+                                gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF, longitudeRef);\r
+                                gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);\r
+                                gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF, latitudeRef);\r
+                                {\r
+                                    double value = longitude;\r
+                                    final double longitudeDegrees = (long) value;\r
+                                    value %= 1;\r
+                                    value *= 60.0;\r
+                                    final double longitudeMinutes = (long) value;\r
+                                    value %= 1;\r
+                                    value *= 60.0;\r
+                                    final double longitudeSeconds = value;\r
+                                    gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LONGITUDE);\r
+                                    gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LONGITUDE,\r
+                                            RationalNumber.valueOf(longitudeDegrees),\r
+                                            RationalNumber.valueOf(longitudeMinutes),\r
+                                            RationalNumber.valueOf(longitudeSeconds));\r
+                                }\r
+                                {\r
+                                    double value = latitude;\r
+                                    final double latitudeDegrees = (long) value;\r
+                                    value %= 1;\r
+                                    value *= 60.0;\r
+                                    final double latitudeMinutes = (long) value;\r
+                                    value %= 1;\r
+                                    value *= 60.0;\r
+                                    final double latitudeSeconds = value;\r
+                                    gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LATITUDE);\r
+                                    gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LATITUDE,\r
+                                            RationalNumber.valueOf(latitudeDegrees),\r
+                                            RationalNumber.valueOf(latitudeMinutes),\r
+                                            RationalNumber.valueOf(latitudeSeconds));\r
+                                }\r
+\r
+                                ExifRewriter rewriter = new ExifRewriter();\r
+                                try {\r
+                                    if (outDir == null) {\r
+                                        outDir = new File(dir, "converted");\r
+                                        outDir.mkdir();\r
                                     }\r
+                                    fos = new FileOutputStream(new File(outDir, imageName));\r
+                                    rewriter.updateExifMetadataLossy(image, fos, outputSet);\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
+                                finally {\r
+                                    if (fos != null) {\r
+                                        fos.close();\r
                                     }\r
                                 }\r
-                                Double dLON = imaLON - maeLON;\r
-                                Double dLAT = imaLAT - maeLAT;\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.atan(y / x));\r
-                                System.out.println("magvar = " + rad);\r
-                                magvar = ret.getOwnerDocument().createElement("magvar");\r
-                                magvar.setTextContent(Double.toString(rad));\r
-                                ret.appendChild(magvar);\r
                             }\r
+\r
+                            Element temp = getCopy(gpx.getOwnerDocument(), wpt);\r
+                            gpx.appendChild(temp);\r
                         }\r
                     }\r
                 }\r
-                mae = map.get(time);\r
             }\r
+        }\r
+    }\r
+       \r
+    static Document document;\r
 \r
-            if (sa < (60000L * 10L)) {\r
-               // System.out.println(dfuk.format(jpt) +" ("+ sa +")");\r
-               return ret;\r
-            }\r
-            return null;\r
-       }\r
+    /**\r
+     * 2012-06-10T05:09:46Z  (日本時間の'2012-06-10T14:09:46')\r
+     */\r
+    public static final String TIME_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ss";\r
+    public static SimpleDateFormat dfjp = new SimpleDateFormat(TIME_FORMAT_STRING);\r
+    public static SimpleDateFormat dfuk = new SimpleDateFormat(TIME_FORMAT_STRING +"'Z'");\r
 \r
-       /**\r
-        * 対象は '*.JPG' のみ対象とする\r
-        */\r
-       public static boolean checkFile(String name) {\r
-               if (name != null && name.toUpperCase().endsWith(".JPG")) {\r
-                       return true;\r
-               }\r
-               return false;\r
-       }\r
+    /**\r
+     * XMLエレメント<trkpt>をTIMEでキー付したHashMapを生成する<br>\r
+     * \r
+     *         <trk><trkseg><trkpt><time>2014-01-01T00:59:09Z</time></trkpt></trkseg></trk>\r
+     * \r
+     * @param trk\r
+     * @param map\r
+     * @throws ParseException\r
+     */\r
+    public static void trkptMap(Element trk, HashMap<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
+                                }\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
 \r
-       /**\r
-        *      <wpt lat="35.25714922" lon="139.15490497">\r
-        *              <ele>62.099998474121094</ele>\r
-        *              <time>2012-06-11T00:44:38Z</time>\r
-        *              <name><![CDATA[写真]]></name>\r
-        *              <link href="2012-06-11_09-44-38.jpg">\r
-        *                      <text>2012-06-11_09-44-38.jpg</text>\r
-        *              </link>\r
-        *      </wpt>\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
-        *\r
-        * @param dir\r
-        * @param csvfile\r
-        * @param delta\r
-        * @throws IOException\r
-        */\r
-       public static Element createWptTag(File iFile, long timestamp, Element trkpt) {\r
-            Element wpt = document.createElement("wpt");\r
-\r
-            NamedNodeMap nodeMap = trkpt.getAttributes();\r
-            if (null != nodeMap) {\r
-                for (int j=0; j < nodeMap.getLength(); j++ ) {\r
-                    if (nodeMap.item(j).getNodeName().equals("lat")) {\r
-                        String lat = nodeMap.item(j).getNodeValue();\r
-                        wpt.setAttribute("lat", lat);\r
+    /**\r
+     * < lat="35.32123832" lon="139.56965631">\r
+     *          <ele>47.20000076293945</ele>\r
+     *          <time>2012-06-15T03:00:29Z</time>\r
+     * </trkpt>\r
+     * @return\r
+     * @param map\r
+     * @param jptime\r
+     * @throws ParseException\r
+     */\r
+    public static Element trkpt(HashMap<Long,Element> map, Date jptime) throws ParseException {\r
+        Double R = 20000000 / Math.PI;                  // 地球の半径(m)\r
+        long sa = 2L * 3600000L;\r
+        long jpt = jptime.getTime();\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
+            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
-                    else if (nodeMap.item(j).getNodeName().equals("lon")) {\r
-                        String lon = nodeMap.item(j).getNodeValue();\r
-                        wpt.setAttribute("lon", lon);\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 dLON = imaLON - maeLON;\r
+                            Double dLAT = imaLAT - maeLAT;\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.atan(y / x));\r
+                            System.out.println("magvar = " + rad);\r
+                            magvar = ret.getOwnerDocument().createElement("magvar");\r
+                            magvar.setTextContent(Double.toString(rad));\r
+                            ret.appendChild(magvar);\r
+                        }\r
                     }\r
                 }\r
             }\r
+            mae = map.get(time);\r
+        }\r
 \r
-            NodeList nodes1 = trkpt.getChildNodes();\r
-            for (int i1=0; i1 < nodes1.getLength(); i1++) {\r
-                Node node1 = nodes1.item(i1);\r
-                if (node1.getNodeName().equals("ele")) {\r
-                    NodeList nodes2 = node1.getChildNodes();\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 eleStr = node2.getNodeValue();\r
-                                Element eleE = document.createElement("ele");\r
-                                eleE.setTextContent(eleStr);\r
-                                wpt.appendChild(eleE);\r
-                            }\r
+        if (sa < (60000L * 10L)) {\r
+            // System.out.println(dfuk.format(jpt) +" ("+ sa +")");\r
+            return ret;\r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * 対象は '*.JPG' のみ対象とする\r
+     * @return \r
+     * @param name\r
+     */\r
+    public static boolean checkFile(String name) {\r
+        return ((name != null) && name.toUpperCase().endsWith(".JPG"));\r
+    }\r
+\r
+    /**\r
+     * <wpt lat="35.25714922" lon="139.15490497">\r
+     *         <ele>62.099998474121094</ele>\r
+     *         <time>2012-06-11T00:44:38Z</time>\r
+     *         <name><![CDATA[写真]]></name>\r
+     *         <link href="2012-06-11_09-44-38.jpg">\r
+     *                 <text>2012-06-11_09-44-38.jpg</text>\r
+     *         </link>\r
+     * </wpt>\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
+     *\r
+     * @return\r
+     * @param iFile\r
+     * @param timestamp\r
+     * @param trkpt\r
+     */\r
+    public static Element createWptTag(File iFile, long timestamp, Element trkpt) {\r
+        Element wpt = document.createElement("wpt");\r
+\r
+        NamedNodeMap nodeMap = trkpt.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 lat = nodeMap.item(j).getNodeValue();\r
+                    wpt.setAttribute("lat", lat);\r
+                    break;\r
+                case "lon":\r
+                    String lon = nodeMap.item(j).getNodeValue();\r
+                    wpt.setAttribute("lon", lon);\r
+                    break;\r
+                }\r
+            }\r
+        }\r
+\r
+        NodeList nodes1 = trkpt.getChildNodes();\r
+        for (int i1=0; i1 < nodes1.getLength(); i1++) {\r
+            Node node1 = nodes1.item(i1);\r
+            NodeList nodes2 = node1.getChildNodes();\r
+            switch (node1.getNodeName()) {\r
+            case "ele":\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 eleStr = node2.getNodeValue();\r
+                            Element eleE = document.createElement("ele");\r
+                            eleE.setTextContent(eleStr);\r
+                            wpt.appendChild(eleE);\r
                         }\r
                     }\r
                 }\r
-                else if (node1.getNodeName().equals("time")) {\r
-                    NodeList nodes2 = node1.getChildNodes();\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 timeStr = node2.getNodeValue();\r
-                                Element timeE = document.createElement("time");\r
-                                timeE.setTextContent(timeStr);\r
-                                wpt.appendChild(timeE);\r
-                            }\r
+                break;\r
+            case "time":\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 timeStr = node2.getNodeValue();\r
+                            Element timeE = document.createElement("time");\r
+                            timeE.setTextContent(timeStr);\r
+                            wpt.appendChild(timeE);\r
                         }\r
                     }\r
                 }\r
-                else if (node1.getNodeName().equals("magvar")) {\r
-                    NodeList nodes2 = node1.getChildNodes();\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 magvarStr = node2.getNodeValue();\r
-                                Element magvarE = document.createElement("magvar");\r
-                                magvarE.setTextContent(magvarStr);\r
-                                wpt.appendChild(magvarE);\r
-                            }\r
+                break;\r
+            case "magvar":\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 magvarStr = node2.getNodeValue();\r
+                            Element magvarE = document.createElement("magvar");\r
+                            magvarE.setTextContent(magvarStr);\r
+                            wpt.appendChild(magvarE);\r
                         }\r
                     }\r
                 }\r
+                break;\r
             }\r
+        }\r
 \r
-            Element name = document.createElement("name");\r
-            name.appendChild(document.createCDATASection("写真"));\r
-            wpt.appendChild(name);\r
+        Element name = document.createElement("name");\r
+        name.appendChild(document.createCDATASection("写真"));\r
+        wpt.appendChild(name);\r
 \r
-            Element link = document.createElement("link");\r
-            link.setAttribute("href", getShortPathName(gpxDir, iFile));\r
-            Element text = document.createElement("text");\r
-            text.setTextContent(iFile.getName());\r
-            link.appendChild(text);\r
-            wpt.appendChild(link);\r
+        Element link = document.createElement("link");\r
+        link.setAttribute("href", getShortPathName(gpxDir, iFile));\r
+        Element text = document.createElement("text");\r
+        text.setTextContent(iFile.getName());\r
+        link.appendChild(text);\r
+        wpt.appendChild(link);\r
 \r
-            return wpt;\r
-       }\r
+        return wpt;\r
+    }\r
        \r
-       static String getShortPathName(File dir, File iFile) {\r
-               String dirPath = dir.getAbsolutePath();\r
-               String filePath = iFile.getAbsolutePath();\r
-               if (filePath.startsWith(dirPath)) {\r
-                       return filePath.substring(dirPath.length()+1);\r
-               }\r
-               else {\r
-                       return filePath;\r
-               }\r
-       }\r
-\r
-       public static Element getCopy(Document doc, Node node) {\r
-               Element root = doc.createElement(node.getNodeName());\r
-\r
-               NamedNodeMap nodeMap = node.getAttributes();\r
-               if (null != nodeMap) {\r
-                       for (int j=0; j < nodeMap.getLength(); j++ ) {\r
-                               root.setAttribute(nodeMap.item(j).getNodeName(), nodeMap.item(j).getNodeValue());\r
-                       }\r
-               }\r
-\r
-               NodeList nodes = node.getChildNodes();\r
-               for (int i=0; i < nodes.getLength(); i++) {\r
-                       Node node2 = nodes.item(i);\r
-                       if (node2.getNodeType() == Node.ELEMENT_NODE) {\r
-                               root.appendChild(getCopy(doc, node2));\r
-                       }\r
-                       else if (node2.getNodeType() == Node.TEXT_NODE) {\r
-                               String str = node2.getNodeValue();\r
-                               Text textContents = doc.createTextNode(str);\r
-                               root.appendChild(textContents);\r
-                       }\r
-                       else if (node2.getNodeType() == Node.CDATA_SECTION_NODE) {\r
-                               String str = node2.getNodeValue();\r
-                               CDATASection cdataSection = doc.createCDATASection(str);\r
-                               root.appendChild(cdataSection);\r
-                       }\r
-               }\r
-               return root;\r
-       }\r
+    static String getShortPathName(File dir, File iFile) {\r
+        String dirPath = dir.getAbsolutePath();\r
+        String filePath = iFile.getAbsolutePath();\r
+        if (filePath.startsWith(dirPath)) {\r
+            return filePath.substring(dirPath.length()+1);\r
+        }\r
+        else {\r
+            return filePath;\r
+        }\r
+    }\r
+\r
+    public static Element getCopy(Document doc, Node node) {\r
+        Element root = doc.createElement(node.getNodeName());\r
+\r
+        NamedNodeMap nodeMap = node.getAttributes();\r
+        if (null != nodeMap) {\r
+            for (int j=0; j < nodeMap.getLength(); j++ ) {\r
+                root.setAttribute(nodeMap.item(j).getNodeName(), nodeMap.item(j).getNodeValue());\r
+            }\r
+        }\r
+\r
+        NodeList nodes = node.getChildNodes();\r
+        for (int i=0; i < nodes.getLength(); i++) {\r
+            Node node2 = nodes.item(i);\r
+            if (node2.getNodeType() == Node.ELEMENT_NODE) {\r
+                root.appendChild(getCopy(doc, node2));\r
+            }\r
+            else if (node2.getNodeType() == Node.TEXT_NODE) {\r
+                String str = node2.getNodeValue();\r
+                Text textContents = doc.createTextNode(str);\r
+                root.appendChild(textContents);\r
+            }\r
+            else if (node2.getNodeType() == Node.CDATA_SECTION_NODE) {\r
+                String str = node2.getNodeValue();\r
+                CDATASection cdataSection = doc.createCDATASection(str);\r
+                root.appendChild(cdataSection);\r
+            }\r
+        }\r
+        return root;\r
+    }\r
        \r
-       /**\r
-        * ファイル名の順序に並び替えるためのソートクラス\r
-        * \r
-        * @author hayashi\r
-        */\r
-       static class FileSort implements Comparator<File>{\r
-               public int compare(File src, File target){\r
-                       int diff = src.getName().compareTo(target.getName());\r
-                       return diff;\r
-               }\r
-       }\r
+    /**\r
+     * ファイル名の順序に並び替えるためのソートクラス\r
+     * \r
+     * @author hayashi\r
+     */\r
+    static class FileSort implements Comparator<File>{\r
+        @Override\r
+        public int compare(File src, File target){\r
+            int diff = src.getName().compareTo(target.getName());\r
+            return diff;\r
+        }\r
+    }\r
 \r
 }
\ No newline at end of file