OSDN Git Service

refacterring
[importpicture/importpicture.git] / importPicture / src / osm / jp / gpx / ImportPicture.java
index 67b428a..901ca0c 100644 (file)
@@ -1,6 +1,8 @@
 package osm.jp.gpx;\r
+\r
 import java.io.*;\r
 import java.nio.channels.FileChannel;\r
+import java.text.DateFormat;\r
 import java.text.DecimalFormat;\r
 import java.text.ParseException;\r
 import java.text.SimpleDateFormat;\r
@@ -10,10 +12,8 @@ import java.util.Calendar;
 import java.util.Comparator;\r
 import java.util.Date;\r
 import java.util.GregorianCalendar;\r
-import java.util.Iterator;\r
-import java.util.Set;\r
+import java.util.Map;\r
 import java.util.TimeZone;\r
-import java.util.TreeMap;\r
 import java.util.logging.LogManager;\r
 import java.util.logging.Logger;\r
 \r
@@ -41,6 +41,11 @@ import org.w3c.dom.*;
 import org.xml.sax.SAXException;\r
 \r
 public class ImportPicture extends Thread {\r
+       /**\r
+        * 実行中に発生したExceptionを保持する場所\r
+        */\r
+       public Exception ex = null;\r
+       \r
     /**\r
      * ログ設定プロパティファイルのファイル内容\r
      */\r
@@ -90,8 +95,13 @@ public class ImportPicture extends Thread {
      * ・精確な時刻との時差を入力することで、撮影日時を補正します。\r
      * ・画像ファイルの更新日付リストをCSV形式のファイルとして出力する。\r
      * ・・結果は、取り込み元のGPXファイルとは別に、元ファイル名にアンダーバー「_」を付加した.ファイルに出力します。\r
+     * \r
+     *  exp) $ java -cp .:AdjustTime.jar:commons-imaging-1.0-SNAPSHOT.jar [AdjustTime.ini]\r
+     *  exp) > java -cp .;AdjustTime.jar;commons-imaging-1.0-SNAPSHOT.jar [AdjustTime.ini]\r
      *\r
      * @param argv\r
+     * argv[0] = INIファイルのパス名\r
+     * \r
      * argv[-] = dummy\r
      * argv[0] = 画像ファイルが格納されているディレクトリ          --> imgDir\r
      * argv[1] = 時刻補正の基準とする画像ファイル                              --> baseFile\r
@@ -104,30 +114,39 @@ public class ImportPicture extends Thread {
      */\r
     public static void main(String[] argv) throws Exception\r
     {\r
-        Date jptime;\r
+        Date imgtime;\r
 \r
+       String paramFilePath = ((argv.length < 1) ? AppParameters.FILE_PATH : argv[0]);\r
+        System.out.println("Param File = '"+ paramFilePath +"'");\r
         ImportPicture obj = new ImportPicture();\r
+        obj.params = new AppParameters(paramFilePath);\r
 \r
-        if (argv.length > 0) {\r
-            obj.imgDir = 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
+        System.out.println(" - param: "+ AppParameters.IMG_TIME +"="+ obj.params.getProperty(AppParameters.IMG_TIME) );\r
+        System.out.println(" - param: "+ AppParameters.IMG_BASE_FILE +"="+ obj.params.getProperty(AppParameters.IMG_BASE_FILE) );\r
+        System.out.println(" - param: "+ AppParameters.GPX_BASETIME +"="+ obj.params.getProperty(AppParameters.GPX_BASETIME) );\r
+        System.out.println(" - param: "+ AppParameters.IMG_SOURCE_FOLDER +"="+ obj.params.getProperty(AppParameters.IMG_SOURCE_FOLDER) );\r
+        System.out.println(" - param: "+ AppParameters.IMG_OUTPUT_FOLDER +"="+ obj.params.getProperty(AppParameters.IMG_OUTPUT_FOLDER) );\r
+        System.out.println(" - param: "+ AppParameters.IMG_OUTPUT +"="+ obj.params.getProperty(AppParameters.IMG_OUTPUT));     \r
+        System.out.println(" - param: "+ AppParameters.IMG_OUTPUT_ALL +"="+ obj.param_ImgOutputAll);\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
+        System.out.println(" - param: "+ AppParameters.GPX_GPXSPLIT +"="+ obj.param_GpxSplit);\r
+        System.out.println(" - param: "+ AppParameters.GPX_NO_FIRST_NODE +"="+ ImportPicture.param_GpxNoFirstNode);        \r
+        System.out.println(" - param: "+ AppParameters.GPX_REUSE +"="+ obj.param_GpxReuse);\r
 \r
-        obj.params = new AppParameters();\r
+        obj.ex = null;\r
+        // argv[0] --> AppParameters.IMG_SOURCE_FOLDER に置き換え\r
+        obj.imgDir = new File(obj.params.getProperty(AppParameters.IMG_SOURCE_FOLDER));\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
+        // argv[1] --> AppParameters.IMG_BASE_FILE に置き換え\r
+        File baseFile = new File(obj.imgDir, obj.params.getProperty(AppParameters.IMG_BASE_FILE));\r
         if (obj.exifBase) {\r
             ImageMetadata meta = Imaging.getMetadata(baseFile);\r
             JpegImageMetadata jpegMetadata = (JpegImageMetadata)meta;\r
@@ -141,26 +160,16 @@ public class ImportPicture extends Thread {
                 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
+               long lastModifyTime = ImportPicture.toEXIFDate(dateTimeOriginal).getTime();\r
+               imgtime = 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
-            Date t = dfjp.parse(timeStr);\r
-            obj.delta = t.getTime() - jptime.getTime();\r
-        }\r
-        catch (ParseException e) {\r
-            System.out.println("'"+ timeStr +"' の書式が違います("+ TIME_FORMAT_STRING +")");\r
-            return;\r
+            imgtime = new Date(baseFile.lastModified());\r
         }\r
 \r
         // 出力ファイル\r
-        obj.outDir = new File(argv[3]);\r
+        // argv[3] --> AppParameters.IMG_OUTPUT に置き換え\r
+        obj.outDir = new File(obj.params.getProperty(AppParameters.IMG_OUTPUT_FOLDER));\r
 \r
         // その他のパラメータを読み取る\r
        String paramStr = obj.params.getProperty(AppParameters.GPX_GPXSPLIT);\r
@@ -170,7 +179,7 @@ public class ImportPicture extends Thread {
         \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
+               ImportPicture.param_GpxNoFirstNode = true;\r
        }\r
        \r
        paramStr = obj.params.getProperty(AppParameters.GPX_REUSE);\r
@@ -224,6 +233,12 @@ public class ImportPicture extends Thread {
                System.out.println("複数のGPXファイルがあるときには、'IMG.OUTPUT_ALL'オプションは指定できません。");\r
                return;\r
             }\r
+            \r
+            java.util.Arrays.sort(files, new java.util.Comparator<File>() {\r
+                       public int compare(File file1, File file2){\r
+                           return file1.getName().compareTo(file2.getName());\r
+                       }\r
+           });\r
             for (File file : files) {\r
                 if (file.isFile()) {\r
                     String filename = file.getName().toUpperCase();\r
@@ -243,26 +258,24 @@ public class ImportPicture extends Thread {
        if ((paramStr != null) && (paramStr.equals(Boolean.toString(true)))) {\r
                obj.exif = true;\r
        }\r
+       \r
+        String timeStr = obj.params.getProperty(AppParameters.IMG_TIME);\r
+        try {\r
+            Date t = toUTCDate(timeStr);\r
+            obj.delta = t.getTime() - imgtime.getTime();\r
+        }\r
+        catch (ParseException e) {\r
+            System.out.println("'"+ timeStr +"' の書式が違います("+ TIME_FORMAT_STRING +")");\r
+            return;\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_ALL +"="+ obj.param_ImgOutputAll);\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
+            obj.join();\r
         } catch(InterruptedException end) {}\r
+        if (obj.ex != null) {\r
+               throw obj.ex;\r
+        }\r
     }\r
     \r
     public File gpxDir;\r
@@ -274,15 +287,16 @@ public class ImportPicture extends Thread {
     public ArrayList<File> gpxFiles = new ArrayList<>();\r
     public AppParameters params;\r
        public boolean param_GpxSplit = false;\r
-       public boolean param_GpxNoFirstNode = false;\r
+       public static 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 boolean param_ImgOutputAll = false;\r
        public String param_GpxSourceFolder = ".";\r
-       public static final long DIFF_MAE_TIME = 3000L; // before 3 secound\r
+    Document document;\r
        \r
+    public static final String TIME_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ss'Z'";\r
+    private static final String EXIF_DATE_TIME_FORMAT_STRING = "yyyy:MM:dd HH:mm:ss";\r
+\r
     @Override\r
     public void run() {\r
         /**\r
@@ -313,6 +327,7 @@ public class ImportPicture extends Thread {
         }\r
         catch(ParserConfigurationException | DOMException | SAXException | IOException | ParseException | ImageReadException | ImageWriteException | IllegalArgumentException | TransformerException e) {\r
                e.printStackTrace();\r
+               this.ex = new Exception(e);\r
         }\r
     }\r
     \r
@@ -328,9 +343,12 @@ public class ImportPicture extends Thread {
      * @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
+        DocumentBuilderFactory factory = null;\r
+        DocumentBuilder        builder = null;\r
+        ElementMapTRKSEG mapTRKSEG = null;\r
+        Node gpx = null;\r
+        \r
+        System.gc();\r
 \r
         String fileName = gpxFile.getName();\r
         String iStr = fileName.substring(0, fileName.length() - 4);\r
@@ -348,123 +366,22 @@ public class ImportPicture extends Thread {
         factory.setIgnoringComments(true);\r
         factory.setValidating(true);\r
 \r
+        // GPXファイルをパースする\r
+        mapTRKSEG = new ElementMapTRKSEG();\r
+        document = mapTRKSEG.parse(gpxFile);\r
+        \r
+        // パースされた mapTRKSEG の中身を出力する\r
+        mapTRKSEG.printinfo();\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
-                        mapTRKSEG.put(new Long(trksegCounter), getCopy(document, newTRKSEG));\r
+        gpx = builder.parse(gpxFile).getFirstChild();\r
 \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
-                       // <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
-        \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
+        // imgDir内の画像ファイルを処理する\r
+               System.out.println("|--------------------------------|--------------------|--------------------|--------------|--------------|--------|------|------|");\r
+               System.out.println("| name                           | Camera Time        | GPStime            |   Latitude   |   Longitude  | ele    |magvar| km/h |");\r
+               System.out.println("|--------------------------------|--------------------|--------------------|--------------|--------------|--------|------|------|");\r
+               proc(imgDir, delta, mapTRKSEG, exif, gpx);\r
+               System.out.println("|--------------------------------|--------------------|--------------------|--------------|--------------|--------|------|------|");\r
 \r
         // 出力\r
         outputFile.getParentFile().mkdirs();\r
@@ -480,7 +397,6 @@ public class ImportPicture extends Thread {
         os = new FileOutputStream(outputFile);\r
         result = new StreamResult(os);\r
         transformer.transform(source, result);\r
-\r
     }\r
     \r
        \r
@@ -491,18 +407,14 @@ public class ImportPicture extends Thread {
      * @throws ImageReadException \r
      * @throws ImageWriteException \r
      */\r
-    boolean proc(File dir, long delta, long gpxStartTime, long gpxEndTime, TreeMap<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
+    boolean proc(File dir, long delta, ElementMapTRKSEG mapTRKSEG, boolean exifWrite, Node gpx) throws ParseException, ImageReadException, IOException, ImageWriteException {\r
         boolean ret = false;\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
+            System.out.print(String.format("|%-32s|", image.getName()));\r
             if (image.isDirectory()) {\r
-                ret = proc(image, delta, gpxStartTime, gpxEndTime, map, exifWrite, gpx);\r
+                ret = proc(image, delta, mapTRKSEG, exifWrite, gpx);\r
                 continue;\r
             }\r
             \r
@@ -512,374 +424,221 @@ public class ImportPicture extends Thread {
                continue;\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
+            Discripter result = procImageFile(image, delta, mapTRKSEG, exifWrite, gpx);\r
+            ret |= result.ret;\r
+            switch (result.control) {\r
+            case Discripter.CONTINUE:\r
+               continue;\r
+            case Discripter.BREAK:\r
+               break;\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
-            if ((uktime.getTime() < gpxStartTime) || (uktime.getTime() > gpxEndTime)) {\r
-                System.out.println(String.format("%20s ", "out of time."));\r
-                if (!this.param_ImgOutputAll) {\r
-                       continue;\r
-                }\r
+        }\r
+        return ret;\r
+    }\r
+    \r
+    class Discripter {\r
+       static final int NEXT = 0;\r
+       static final int CONTINUE = -1;\r
+       static final int BREAK = 1;\r
+       \r
+       public boolean ret;\r
+       public int control;\r
+       public Discripter(boolean ret) {\r
+               this.ret = ret;\r
+               this.control = Discripter.NEXT;\r
+       }\r
+    }\r
+    \r
+    Discripter procImageFile(File image, long delta, ElementMapTRKSEG mapTRKSEG, 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
+        Discripter result = new Discripter(false);\r
+        \r
+        // itime <-- 画像ファイルの撮影時刻\r
+        //                     ファイルの更新日時/EXIFの撮影日時\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
+                result.control = Discripter.CONTINUE;\r
+                return result;\r
             }\r
-\r
-               // 時刻uktimeにおける<magver>をtrkptに追加する\r
-            Element trkptE = trkpt(map, uktime);\r
-            String eleStr = "-";\r
-            String magvarStr = "-";\r
-            String speedStr = "-";\r
-            double latitude = 90.5D;\r
-            double longitude = 180.5D;\r
-            TagTrkpt trkptT = null;\r
-            if (trkptE == null) {\r
-                System.out.println(String.format("%20s ", "Out of GPX logging time."));\r
-                if (!this.param_ImgOutputAll) {\r
-                       continue;\r
-                }\r
+            TiffImageMetadata exif = jpegMetadata.getExif();\r
+            if (exif == null) {\r
+                System.out.println("'"+ image.getAbsolutePath() +"' にEXIF情報がありません");\r
+                result.control = Discripter.CONTINUE;\r
+                return result;\r
             }\r
-            else {\r
-                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
-                latitude = trkptT.lat;\r
-                longitude = trkptT.lon;\r
-                \r
-                if (trkptT.eleStr != null) {\r
-                       eleStr = new String(trkptT.eleStr);\r
-                }\r
-                \r
-                if (trkptT.magvarStr != null) {\r
-                       magvarStr = new String(trkptT.magvarStr);\r
-                }\r
-                \r
-                if (trkptT.speedStr != null) {\r
-                       speedStr = new String(trkptT.speedStr);\r
-                }\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
+               String dateTimeOriginal = exif.getFieldValue(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL)[0];\r
+               itime = ImportPicture.toEXIFDate(dateTimeOriginal);\r
+        }\r
+        System.out.print(String.format("%20s|", toUTCString(itime)));\r
+\r
+        // uktime <-- 画像撮影時刻に対応するGPX時刻(補正日時)\r
+        Date correctedtime = new Date(itime.getTime() + delta);\r
+        System.out.print(String.format("%20s|", toUTCString(correctedtime)));\r
+\r
+               // 時刻uktimeにおける<magver>をtrkptに追加する\r
+        String eleStr = "-";\r
+        String magvarStr = "-";\r
+        String speedStr = "-";\r
+        double latitude = 90.5D;\r
+        double longitude = 180.5D;\r
+        //Element trkptE = null;\r
+        TagTrkpt trkptT = null;\r
+\r
+        for (Map.Entry<Date,ElementMapTRKPT> map : mapTRKSEG.entrySet()) {\r
+               ElementMapTRKPT mapTRKPT = map.getValue();\r
+               trkptT = mapTRKPT.getValue(correctedtime);\r
+            if (trkptT != null) {\r
+                break;\r
             }\r
+        }\r
 \r
-            ret = true;\r
-            FileOutputStream fos = null;\r
-            outDir.mkdir();\r
-\r
-            if (exifWrite) {\r
-                TiffOutputSet outputSet = 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
-                if (trkptE != null) {\r
-                       //---- EXIF GPS elevation/ALTITUDE ----\r
-                       if (eleStr.equals("-") == false) {\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 magvar/IMG_DIRECTION ----\r
-                       if (magvarStr.equals("-") == false) {\r
-                           final double magvar = Double.parseDouble(magvarStr);\r
-                           gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION);\r
-                           gpsDir.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION, RationalNumber.valueOf(magvar));\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
-\r
-                ExifRewriter rewriter = new ExifRewriter();\r
-                try {\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
-                if (Boolean.parseBoolean(params.getProperty(AppParameters.GPX_OUTPUT_WPT))) {\r
-                       if (trkptT != null) {\r
-                       Element temp = createWptTag(image, itime.getTime(), trkptT.trkpt);\r
-                        gpx.appendChild(temp);\r
-                       }\r
-                }\r
+        if (trkptT == null) {\r
+            System.out.print(String.format("%-14s|%-14s|", "", ""));\r
+            System.out.println(String.format("%8s|%6s|%6s|", "", "", ""));\r
+            if (!this.param_ImgOutputAll) {\r
+                result.control = Discripter.CONTINUE;\r
+                return result;\r
             }\r
-            else {\r
-               if (this.param_ImgOutputAll) {\r
-                       // EXIFの変換を伴わない単純なファイルコピー\r
-                       FileInputStream sStream = new FileInputStream(image);\r
-                       FileInputStream dStream = new FileInputStream(new File(outDir, imageName));\r
-                    FileChannel srcChannel = sStream.getChannel();\r
-                    FileChannel destChannel = dStream.getChannel();\r
-                    try {\r
-                        srcChannel.transferTo(0, srcChannel.size(), destChannel);\r
-                    }\r
-                    finally {\r
-                        srcChannel.close();\r
-                        destChannel.close();\r
-                        sStream.close();\r
-                        dStream.close();\r
-                    }\r
-               }\r
+        }\r
+        else {\r
+            latitude = trkptT.lat;\r
+            longitude = trkptT.lon;\r
+            \r
+            if (trkptT.eleStr != null) {\r
+               eleStr = new String(trkptT.eleStr);\r
+            }\r
+            \r
+            if (trkptT.magvarStr != null) {\r
+               magvarStr = new String(trkptT.magvarStr);\r
+            }\r
+            \r
+            if (trkptT.speedStr != null) {\r
+               speedStr = new String(trkptT.speedStr);\r
             }\r
+            //System.out.print(String.format("%-14s|%-14s|", (new Double(latitude)).toString(), (new Double(longitude)).toString()));\r
+            System.out.print(String.format("%14.10f|%14.10f|", latitude, longitude));\r
+            System.out.println(String.format("%8s|%6s|%6s|", eleStr, magvarStr, speedStr));\r
         }\r
-        return ret;\r
-    }\r
-       \r
-    static Document document;\r
 \r
+        result.ret = true;\r
+        FileOutputStream fos = null;\r
+        outDir.mkdir();\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
-     * XMLエレメント<trkpt>をTIMEでキー付したHashMapを生成する<br>\r
-     * \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 void trkptMap(Element trkseg, TreeMap<Long,Element> map) throws ParseException {\r
-        dfuk.setTimeZone(TimeZone.getTimeZone("GMT"));\r
+        if (exifWrite) {\r
+            TiffOutputSet outputSet = null;\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
+            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
-    }\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
+            if (outputSet == null) {\r
+                System.out.println("added : new tiff output set");\r
+                outputSet = new TiffOutputSet();\r
+            }\r
 \r
-                // <MAGVAR>がなければ、\r
-                // 直前の位置と、現在地から進行方向を求める\r
-               // 経度(longitude)と経度から進行方向を求める\r
-                if (Complementation.param_GpxOverwriteMagvar) {\r
-                       comp.complementationMagvar();\r
-                }\r
+            //---- EXIF_TAG_DATE_TIME_ORIGINAL / 「撮影日時/オリジナル画像の生成日時」----\r
+            TiffOutputDirectory exifDir = outputSet.getOrCreateExifDirectory();\r
+            {\r
+                Calendar cal = GregorianCalendar.getInstance();\r
+                cal.setTimeZone(TimeZone.getTimeZone("UTC"));\r
+                cal.setTime(correctedtime);\r
+                exifDir.removeField(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);\r
+                exifDir.add(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL, ImportPicture.toEXIFString(cal.getTime()));\r
+            }\r
 \r
-                // 緯度・経度と時間差から速度(km/h)を求める\r
-                if (Complementation.param_GpxOutputSpeed) {\r
-                       comp.complementationSpeed();\r
-                }\r
-                imaE = (Element)(comp.imaTag.trkpt.cloneNode(true));\r
+            //---- EXIF GPS_TIME_STAMP ----\r
+            TiffOutputDirectory gpsDir = outputSet.getOrCreateGPSDirectory();\r
+            {\r
+                Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));\r
+                cal.setTimeZone(TimeZone.getTimeZone("GMT+00"));\r
+                cal.setTime(correctedtime);\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
-        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 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
+            if (trkptT != null) {\r
+                //---- EXIF GPS elevation/ALTITUDE ----\r
+                if (eleStr.equals("-") == false) {\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
-        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
+                //---- EXIF GPS magvar/IMG_DIRECTION ----\r
+                if (magvarStr.equals("-") == false) {\r
+                    final double magvar = Double.parseDouble(magvarStr);\r
+                    gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION);\r
+                    gpsDir.add(GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION, RationalNumber.valueOf(magvar));\r
+                }\r
 \r
-            if (Math.abs(jpt - t) < sa) {\r
-                sa = Math.abs(jpt - t);\r
-                ret = map.get(time);\r
+                //---- EXIF GPS_ ----\r
+                longitude = Math.abs(longitude);\r
+                latitude = Math.abs(latitude);\r
+                outputSet.setGPSInDegrees(longitude, latitude);\r
             }\r
-        }\r
 \r
-        if (sa < (60000L * 10L)) {\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
+            ExifRewriter rewriter = new ExifRewriter();\r
+            try {\r
+                fos = new FileOutputStream(new File(outDir, image.getName()));\r
+                rewriter.updateExifMetadataLossy(image, fos, outputSet);\r
+            }\r
+            finally {\r
+                if (fos != null) {\r
+                    fos.close();\r
+                }\r
+            }\r
 \r
-            if (Math.abs(jpt - t) < diffTime) {\r
-               diffTime = Math.abs(jpt - t);\r
-                ret = map.get(time);\r
+            if (Boolean.parseBoolean(params.getProperty(AppParameters.GPX_OUTPUT_WPT))) {\r
+               if (trkptT != null) {\r
+                       Element temp = createWptTag(image, itime.getTime(), trkptT.trkpt);\r
+                    gpx.appendChild(temp);\r
+               }\r
             }\r
         }\r
-\r
-        if (diffTime < (60000L * 10L)) {\r
-               // GPX時刻との差が10分以内なら有効\r
-               if (diffTime < (imaTrkpt.time.getTime() - 1000)) {\r
-                       // 元の時刻との差が1秒以上あること\r
-                return ret;\r
+        else {\r
+               if (this.param_ImgOutputAll) {\r
+               // EXIFの変換を伴わない単純なファイルコピー\r
+                       FileInputStream sStream = new FileInputStream(image);\r
+                       FileInputStream dStream = new FileInputStream(new File(outDir, image.getName()));\r
+                FileChannel srcChannel = sStream.getChannel();\r
+                FileChannel destChannel = dStream.getChannel();\r
+                try {\r
+                    srcChannel.transferTo(0, srcChannel.size(), destChannel);\r
+                }\r
+                finally {\r
+                    srcChannel.close();\r
+                    destChannel.close();\r
+                    sStream.close();\r
+                    dStream.close();\r
+                }\r
                }\r
         }\r
-        return null;\r
+        result.control = Discripter.NEXT;\r
+        return result;\r
     }\r
-    \r
+       \r
     /**\r
      * 対象は '*.JPG' のみ対象とする\r
      * @return \r
@@ -993,7 +752,7 @@ public class ImportPicture extends Thread {
         wpt.appendChild(name);\r
 \r
         Element link = document.createElement("link");\r
-        link.setAttribute("href", getShortPathName(imgDir, iFile));\r
+        link.setAttribute("href", ImportPicture.getShortPathName(imgDir, iFile));\r
         Element text = document.createElement("text");\r
         text.setTextContent(iFile.getName());\r
         link.appendChild(text);\r
@@ -1001,6 +760,42 @@ public class ImportPicture extends Thread {
 \r
         return wpt;\r
     }\r
+    \r
+    /**\r
+     * DateをEXIFの文字列に変換する。\r
+     * 注意:EXiFの撮影時刻はUTC時間ではない\r
+     * @param localdate\r
+     * @return\r
+     */\r
+    public static String toEXIFString(Date localdate) {\r
+       DateFormat dfUTC = new SimpleDateFormat(EXIF_DATE_TIME_FORMAT_STRING);\r
+       return dfUTC.format(localdate);\r
+    }\r
+    \r
+    /**\r
+     * EXIFの文字列をDateに変換する。\r
+     * 注意:EXiFの撮影時刻はUTC時間ではない\r
+     * @param timeStr\r
+     * @return\r
+     * @throws ParseException\r
+     */\r
+    public static Date toEXIFDate(String timeStr) throws ParseException {\r
+       DateFormat dfUTC = new SimpleDateFormat(EXIF_DATE_TIME_FORMAT_STRING);\r
+       //dfUTC.setTimeZone(TimeZone.getTimeZone("UTC"));\r
+       return dfUTC.parse(timeStr);\r
+    }\r
+       \r
+    public static String toUTCString(Date localdate) {\r
+       DateFormat dfUTC = new SimpleDateFormat(TIME_FORMAT_STRING);\r
+       dfUTC.setTimeZone(TimeZone.getTimeZone("UTC"));\r
+       return dfUTC.format(localdate);\r
+    }\r
+       \r
+    public static Date toUTCDate(String timeStr) throws ParseException {\r
+       DateFormat dfUTC = new SimpleDateFormat(TIME_FORMAT_STRING);\r
+       dfUTC.setTimeZone(TimeZone.getTimeZone("UTC"));\r
+       return dfUTC.parse(timeStr);\r
+    }\r
        \r
     static String getShortPathName(File dir, File iFile) {\r
         String dirPath = dir.getAbsolutePath();\r
@@ -1012,43 +807,13 @@ public class ImportPicture extends Thread {
             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
      * \r
      * @author hayashi\r
      */\r
-    static class FileSort implements Comparator<File>{\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
@@ -1060,7 +825,7 @@ public class ImportPicture extends Thread {
      * JPEGファイルフィルター\r
      * @author yuu\r
      */\r
-       class JpegFileFilter implements FilenameFilter{\r
+       class JpegFileFilter implements FilenameFilter {\r
        public boolean accept(File dir, String name) {\r
                        if (name.toUpperCase().matches(".*\\.JPG$")) {\r
                                return true;\r