OSDN Git Service

リファクタリング
authoryuuhayashi <hayashi.yuu@gmail.com>
Mon, 3 Oct 2016 04:29:36 +0000 (13:29 +0900)
committeryuuhayashi <hayashi.yuu@gmail.com>
Mon, 3 Oct 2016 04:29:36 +0000 (13:29 +0900)
importPicture/src/osm/jp/gpx/Complementation.java [new file with mode: 0644]
importPicture/src/osm/jp/gpx/ImportPicture.java

diff --git a/importPicture/src/osm/jp/gpx/Complementation.java b/importPicture/src/osm/jp/gpx/Complementation.java
new file mode 100644 (file)
index 0000000..7b1914f
--- /dev/null
@@ -0,0 +1,194 @@
+package osm.jp.gpx;
+
+import java.text.ParseException;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class Complementation {
+
+       public Complementation(Element imaE, Element maeE) throws ParseException {
+        // <MAGVAR>がなければ、
+        // 直前の位置と、現在地から進行方向を求める
+        NodeList nodes3 = imaE.getChildNodes();
+        for (int i3=0; i3 < nodes3.getLength(); i3++) {
+            Node node4 = nodes3.item(i3);
+            String nodename = node4.getNodeName().toLowerCase();
+            if (nodename.equals("magvar")) {
+                magvar = (Element) node4;
+                break;
+            }
+            else if (nodename.equals("time")) {
+                String timeStr = ((Element)node4).getTextContent();
+                setImaTIME(ImportPicture.dfuk.parse(timeStr).getTime());
+                break;
+            }
+        }
+        
+        NamedNodeMap nodeMap = imaE.getAttributes();
+        for (int j=0; j < nodeMap.getLength(); j++ ) {
+            switch (nodeMap.item(j).getNodeName()) {
+                case "lat":
+                    String latStr = nodeMap.item(j).getNodeValue();
+                    imaLAT = new Double(latStr);
+                    break;
+                case "lon":
+                    String lonStr = nodeMap.item(j).getNodeValue();
+                    imaLON = new Double(lonStr);
+                    break;
+            }
+        }
+
+        nodes3 = maeE.getChildNodes();
+        for (int i3=0; i3 < nodes3.getLength(); i3++) {
+            Node node4 = nodes3.item(i3);
+            if (node4.getNodeName().toLowerCase().equals("time")) {
+                String timeStr = node4.getTextContent();
+                maeTIME = ImportPicture.dfuk.parse(timeStr).getTime();
+                break;
+            }
+        }
+
+        nodeMap = maeE.getAttributes();
+        for (int j=0; j < nodeMap.getLength(); j++ ) {
+            switch (nodeMap.item(j).getNodeName()) {
+                case "lat":
+                    String latStr = nodeMap.item(j).getNodeValue();
+                    maeLAT = new Double(latStr);
+                    break;
+                case "lon":
+                    String lonStr = nodeMap.item(j).getNodeValue();
+                    maeLON = new Double(lonStr);
+                    break;
+            }
+        }
+       }
+
+    public static final Double R = 20000000 / Math.PI;
+    public static final double dLat = 0.00453D;                        // 1km距離を表す緯度(差分)
+    public static final double dLon = 0.005588D;               // 1km距離を表す経度(差分)
+
+    public long imaTIME = 0L;
+    public long maeTIME = 0L;
+    public Double maeLAT = null;
+    public Double maeLON = null;
+    public Double imaLAT = null;
+    public Double imaLON =null;
+    public Element magvar = null;
+    
+    
+    /**
+     * 緯度・経度と時間差から速度(m/sec)を求める
+     * 
+     */
+    public void complementationSpeed(Element imaE) throws ParseException {
+               double lon = (imaLON - maeLON);
+               lon = lon * dLon;
+               double lat = (imaLAT - maeLAT);
+               lat = lat * dLat;
+
+        Element speed = imaE.getOwnerDocument().createElement("speed");
+        String str = Double.toString((Math.sqrt(Math.pow(lon, 2) + Math.pow(lat, 2)) / (imaTIME - maeTIME)));
+        int iDot = str.indexOf('.');
+        if (iDot > 0) {
+            str = str.substring(0, iDot+2);
+        }
+        speed.setTextContent(str);
+        imaE.appendChild(speed);
+    }
+
+    /**
+     *  経度(longitude)と経度から進行方向を求める
+     * @param imaE
+     * @param imaLON
+     * @param imaLAT
+     * @param imaTIME
+     * @param maeLON
+     * @param maeLAT
+     * @param maeTIME
+     * @throws ParseException
+     */
+    public void complementationMagvar(Element imaE) throws ParseException {
+        Double r = Math.cos(Math.toRadians((imaLAT + maeLAT) / 2)) * R;
+        Double x = Math.toRadians(imaLON - maeLON) * r;
+        Double y = Math.toRadians(imaLAT - maeLAT) * R;
+        double rad = Math.toDegrees(Math.atan2(y, x));
+        
+        if (y >= 0) {
+            if (x >= 0) {
+                rad = 0 - (rad - 90);
+            }
+            else {
+                rad = 360 - (rad - 90);
+            }
+        }
+        else {
+            if (x >= 0) {
+                rad = 90 - rad;
+            }
+            else {
+                rad = 90 - rad;
+            }
+        }
+
+        Element magvar = imaE.getOwnerDocument().createElement("magvar");
+        String str = Double.toString(rad);
+        int iDot = str.indexOf('.');
+        if (iDot > 0) {
+            str = str.substring(0, iDot);
+        }
+        magvar.setTextContent(str);
+        imaE.appendChild(magvar);
+    }
+
+       public long getImaTIME() {
+               return imaTIME;
+       }
+
+       public void setImaTIME(long imaTIME) {
+               this.imaTIME = imaTIME;
+       }
+
+       public long getMaeTIME() {
+               return maeTIME;
+       }
+
+       public void setMaeTIME(long maeTIME) {
+               this.maeTIME = maeTIME;
+       }
+
+       public Double getMaeLAT() {
+               return maeLAT;
+       }
+
+       public void setMaeLAT(Double maeLAT) {
+               this.maeLAT = maeLAT;
+       }
+
+       public Double getMaeLON() {
+               return maeLON;
+       }
+
+       public void setMaeLON(Double maeLON) {
+               this.maeLON = maeLON;
+       }
+
+       public Double getImaLAT() {
+               return imaLAT;
+       }
+
+       public void setImaLAT(Double imaLAT) {
+               this.imaLAT = imaLAT;
+       }
+
+       public Double getImaLON() {
+               return imaLON;
+       }
+
+       public void setImaLON(Double imaLON) {
+               this.imaLON = imaLON;
+       }
+
+}
index f37aa2d..03ed192 100644 (file)
@@ -276,10 +276,6 @@ public class ImportPicture extends Thread {
                         <sat>9</sat>\r
                 </wpt>\r
          */\r
-        DocumentBuilderFactory factory;\r
-        DocumentBuilder        builder;\r
-        Node gpx;\r
-\r
         try {\r
                if (params.getProperty(AppParameters.IMG_OUTPUT).equals(Boolean.toString(true))) {\r
                 outDir = new File(outDir, imgDir.getName());\r
@@ -289,136 +285,156 @@ public class ImportPicture extends Thread {
                }\r
 \r
             for (File gpxFile : this.gpxFiles) {\r
-                String fileName = gpxFile.getName();\r
-                String iStr = fileName.substring(0, fileName.length() - 4);\r
-\r
-                File outputFile = new File(outDir, iStr +"_.gpx");\r
-                System.out.println(gpxFile.getAbsolutePath() + " => "+ outputFile.getAbsolutePath());\r
-                System.out.println("           時差: "+ (delta / 1000) +"(sec)");\r
-                System.out.println("    Target GPX: ["+ gpxFile.getAbsolutePath() +"]");\r
-                System.out.println("          EXIF: "+ (exif ? ("convert to '" + outDir.getAbsolutePath() +"'") : "off"));\r
-                System.out.println();\r
-\r
-                factory = DocumentBuilderFactory.newInstance();\r
-                builder = factory.newDocumentBuilder();\r
-                factory.setIgnoringElementContentWhitespace(true);\r
-                factory.setIgnoringComments(true);\r
-                factory.setValidating(true);\r
-\r
-                // GPX file --> Node root\r
-                DOMImplementation domImpl = builder.getDOMImplementation();\r
-                document = domImpl.createDocument("", "gpx", null);\r
-\r
-                /*\r
-                 * <gpx>\r
-                 *   <trk>\r
-                 *     <name><![CDATA[Tracked with OSMTracker for Android?]]></name>\r
-                 *     <cmt><![CDATA[警告: HDOP values aren't the HDOP as returned by the GPS device. They're approximated from the location accuracy in meters.]]></cmt>\r
-                 *     <trkseg>\r
-                 *       <trkpt lat="35.32123832" lon="139.56965631">\r
-                 *         <ele>47.20000076293945</ele>\r
-                 *         <time>2012-06-15T03:00:29Z</time>\r
-                 *         <hdop>0.5</hdop>\r
-                 *       </trkpt>\r
-                 *     </trkseg>\r
-                 *   </trk>\r
-                 *   <wpt lat="35.2564461" lon="139.15437809"></wpt>\r
-                 * </gpx>\r
-                 */\r
-                TreeMap<Long,Element> map = new TreeMap<>();\r
-                TreeMap<Long,Element> mapTRKSEG = new TreeMap<>();\r
-                Element trk = null;\r
-                gpx    = builder.parse(gpxFile).getFirstChild();\r
-                Document doc = 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 = doc.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(doc, nodeTRKPT));\r
-                                    }\r
-                                }\r
-                                mapTRKSEG.put(new Long(trksegCounter), getCopy(doc, newTRKSEG));\r
+               procGPXfile(gpxFile);\r
+            }\r
+        }\r
+        catch(ParserConfigurationException | DOMException | SAXException | IOException | ParseException | ImageReadException | ImageWriteException | IllegalArgumentException | TransformerException e) {\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * 個別のGPXファイルを処理する\r
+     * \r
+     * @throws ParserConfigurationException \r
+     * @throws IOException \r
+     * @throws SAXException \r
+     * @throws ParseException \r
+     * @throws ImageWriteException \r
+     * @throws ImageReadException \r
+     * @throws TransformerException \r
+     */\r
+    void procGPXfile(File gpxFile) throws ParserConfigurationException, SAXException, IOException, ParseException, ImageReadException, ImageWriteException, TransformerException {\r
+        DocumentBuilderFactory factory;\r
+        DocumentBuilder        builder;\r
+        Node gpx;\r
 \r
-                                // <trk>から<trkseg>を削除する。\r
-                                trk.removeChild(nodeTRKSEG);\r
+        String fileName = gpxFile.getName();\r
+        String iStr = fileName.substring(0, fileName.length() - 4);\r
+\r
+        File outputFile = new File(outDir, iStr +"_.gpx");\r
+        System.out.println(gpxFile.getAbsolutePath() + " => "+ outputFile.getAbsolutePath());\r
+        System.out.println("           時差: "+ (delta / 1000) +"(sec)");\r
+        System.out.println("    Target GPX: ["+ gpxFile.getAbsolutePath() +"]");\r
+        System.out.println("          EXIF: "+ (exif ? ("convert to '" + outDir.getAbsolutePath() +"'") : "off"));\r
+        System.out.println();\r
+\r
+        factory = DocumentBuilderFactory.newInstance();\r
+        builder = factory.newDocumentBuilder();\r
+        factory.setIgnoringElementContentWhitespace(true);\r
+        factory.setIgnoringComments(true);\r
+        factory.setValidating(true);\r
+\r
+        // GPX file --> Node root\r
+        DOMImplementation domImpl = builder.getDOMImplementation();\r
+        document = domImpl.createDocument("", "gpx", null);\r
+\r
+        /*\r
+         * <gpx>\r
+         *   <trk>\r
+         *     <name><![CDATA[Tracked with OSMTracker for Android?]]></name>\r
+         *     <cmt><![CDATA[警告: HDOP values aren't the HDOP as returned by the GPS device. They're approximated from the location accuracy in meters.]]></cmt>\r
+         *     <trkseg>\r
+         *       <trkpt lat="35.32123832" lon="139.56965631">\r
+         *         <ele>47.20000076293945</ele>\r
+         *         <time>2012-06-15T03:00:29Z</time>\r
+         *         <hdop>0.5</hdop>\r
+         *       </trkpt>\r
+         *     </trkseg>\r
+         *   </trk>\r
+         *   <wpt lat="35.2564461" lon="139.15437809"></wpt>\r
+         * </gpx>\r
+         */\r
+        TreeMap<Long,Element> map = new TreeMap<>();\r
+        TreeMap<Long,Element> mapTRKSEG = new TreeMap<>();\r
+        Element trk = null;\r
+        gpx    = builder.parse(gpxFile).getFirstChild();\r
+        Document doc = 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 = doc.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(doc, nodeTRKPT));\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に、<trkpy>を割り付ける\r
-                            trkptMap(newTRKSEG, map);\r
-                        }\r
+                        mapTRKSEG.put(new Long(trksegCounter), getCopy(doc, newTRKSEG));\r
+\r
+                        // <trk>から<trkseg>を削除する。\r
+                        trk.removeChild(nodeTRKSEG);\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
-                               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|");\r
-                               System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
-                               proc(imgDir, delta, gpxStartTime, gpxEndTime, map, exif, gpx);\r
-                               System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
-\r
-                // 出力\r
-                DOMSource source = new DOMSource(gpx);\r
-                FileOutputStream os = new FileOutputStream(outputFile);\r
-                StreamResult result = new StreamResult(os);\r
-                TransformerFactory transFactory = TransformerFactory.newInstance();\r
-                Transformer transformer = transFactory.newTransformer();\r
-                transformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
-                transformer.setOutputProperty(OutputKeys.METHOD, "xml");\r
-                transformer.transform(source, result);         \r
-                if (exif) {\r
-                    outputFile = new File(outDir, iStr +"_.gpx");\r
-                    os = new FileOutputStream(outputFile);\r
-                    result = new StreamResult(os);\r
-                    transformer.transform(source, result);\r
+                // <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に、<trkpy>を割り付ける\r
+                    trkptMap(newTRKSEG, map);\r
                 }\r
             }\r
         }\r
-        catch(ParserConfigurationException | DOMException | SAXException | IOException | ParseException | ImageReadException | ImageWriteException | IllegalArgumentException | TransformerException e) {\r
-        }\r
+        \r
+        /*\r
+         * GPXへ割りつける開始時刻と終了時刻を求める\r
+         */\r
+               long gpxStartTime = (new Date()).getTime();             // 対象とする開始時刻(現在時刻)\r
+               long gpxEndTime = 0L;                                                   // 対象とする終了時刻\r
+               Set<Long> keySet = map.keySet();  //すべてのキー値を取得\r
+               for (Long timeLong : keySet) {\r
+                       long gpxTime = timeLong;\r
+                       if (gpxStartTime > gpxTime) {\r
+                            gpxStartTime = gpxTime;\r
+                       }\r
+                       if (gpxEndTime < gpxTime) {\r
+                            gpxEndTime = gpxTime;\r
+                       }\r
+               }\r
+                \r
+               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| speed|");\r
+               System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|------|");\r
+               proc(imgDir, delta, gpxStartTime, gpxEndTime, map, exif, gpx);\r
+               System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|------|");\r
+\r
+        // 出力\r
+        DOMSource source = new DOMSource(gpx);\r
+        FileOutputStream os = new FileOutputStream(outputFile);\r
+        StreamResult result = new StreamResult(os);\r
+        TransformerFactory transFactory = TransformerFactory.newInstance();\r
+        Transformer transformer = transFactory.newTransformer();\r
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
+        transformer.setOutputProperty(OutputKeys.METHOD, "xml");\r
+        transformer.transform(source, result);         \r
+\r
+        outputFile = new File(outDir, iStr +"_.gpx");\r
+        os = new FileOutputStream(outputFile);\r
+        result = new StreamResult(os);\r
+        transformer.transform(source, result);\r
+\r
     }\r
+    \r
        \r
     /**\r
      * 再帰メソッド\r
@@ -488,6 +504,7 @@ public class ImportPicture extends Thread {
             \r
             String eleStr = "-";\r
             String magvarStr = "-";\r
+            String speedStr = "-";\r
             NodeList nodes = wpt.getChildNodes();      // 子ノードを取得\r
             for (int i4 = 0; i4 < nodes.getLength(); i4++) {\r
                 Node node = nodes.item(i4);\r
@@ -499,12 +516,15 @@ public class ImportPicture extends Thread {
                         case "magvar":\r
                             magvarStr = node.getFirstChild().getNodeValue();\r
                             break;\r
+                        case "speed":\r
+                            speedStr = node.getFirstChild().getNodeValue();\r
+                            break;\r
                     }\r
                 }\r
             }\r
 \r
             System.out.print(String.format("%12s %12s|", latStr, lonStr));\r
-            System.out.println(String.format("%8s|%6s|", eleStr, magvarStr));\r
+            System.out.println(String.format("%8s|%6s|%6s|", eleStr, magvarStr, speedStr));\r
             ret = true;\r
 \r
             if (exifWrite) {\r
@@ -689,7 +709,6 @@ public class ImportPicture extends Thread {
      * @throws ParseException\r
      */\r
     public Element trkpt(TreeMap<Long,Element> map, Date jptime) throws ParseException {\r
-        Double R = 20000000 / Math.PI;\r
         long sa = 2L * 3600000L;\r
         long jpt = jptime.getTime();\r
         Element ret = null;\r
@@ -700,97 +719,27 @@ public class ImportPicture extends Thread {
         while (keyIte.hasNext()) {    //ループ。反復子iteratorによる キー 取得\r
             Long time = keyIte.next();\r
             long t = time;\r
+\r
             if (Math.abs(jpt - t) < sa) {\r
                 sa = Math.abs(jpt - t);\r
                 ret = map.get(time);\r
 \r
                 // <MAGVAR>がなければ、\r
                 // 直前の位置と、現在地から進行方向を求める\r
-                NodeList nodes3 = ret.getChildNodes();\r
                 Element magvar = null;\r
-                for (int i3=0; i3 < nodes3.getLength(); i3++) {\r
-                    Node node4 = nodes3.item(i3);\r
-                    if (node4.getNodeName().toLowerCase().equals("magvar")) {\r
-                        magvar = (Element) node4;\r
-                        break;\r
-                    }\r
-                }\r
-                if ((magvar == null) || param_GpxOverwriteMagvar) {\r
-                    if (mae != null) {\r
-                        Double maeLAT = null;\r
-                        Double maeLON = null;\r
-                        Double imaLAT = null;\r
-                        Double imaLON =null;\r
-\r
-                        // 経度(longitude)と経度から進行方向を求める\r
-                        NamedNodeMap nodeMap = mae.getAttributes();\r
-                        if (null != nodeMap) {\r
-                            for (int j=0; j < nodeMap.getLength(); j++ ) {\r
-                                switch (nodeMap.item(j).getNodeName()) {\r
-                                    case "lat":\r
-                                        String latStr = nodeMap.item(j).getNodeValue();\r
-                                        maeLAT = new Double(latStr);\r
-                                        break;\r
-                                    case "lon":\r
-                                        String lonStr = nodeMap.item(j).getNodeValue();\r
-                                        maeLON = new Double(lonStr);\r
-                                        break;\r
-                                }\r
-                            }\r
-                            nodeMap = ret.getAttributes();\r
-                            for (int j=0; j < nodeMap.getLength(); j++ ) {\r
-                                switch (nodeMap.item(j).getNodeName()) {\r
-                                    case "lat":\r
-                                        String latStr = nodeMap.item(j).getNodeValue();\r
-                                        imaLAT = new Double(latStr);\r
-                                        break;\r
-                                    case "lon":\r
-                                        String lonStr = nodeMap.item(j).getNodeValue();\r
-                                        imaLON = new Double(lonStr);\r
-                                        break;\r
-                                }\r
-                            }\r
-                            Double r = Math.cos(Math.toRadians((imaLAT + maeLAT) / 2)) * R;\r
-                            Double x = Math.toRadians(imaLON - maeLON) * r;\r
-                            Double y = Math.toRadians(imaLAT - maeLAT) * R;\r
-                            double rad = Math.toDegrees(Math.atan2(y, x));\r
-                            \r
-                            if (y >= 0) {\r
-                                if (x >= 0) {\r
-                                    rad = 0 - (rad - 90);\r
-                                }\r
-                                else {\r
-                                    rad = 360 - (rad - 90);\r
-                                }\r
-                            }\r
-                            else {\r
-                                if (x >= 0) {\r
-                                    rad = 90 - rad;\r
-                                }\r
-                                else {\r
-                                    rad = 90 - rad;\r
-                                }\r
-                            }\r
 \r
-                            magvar = ret.getOwnerDocument().createElement("magvar");\r
-                            String str = Double.toString(rad);\r
-                            int iDot = str.indexOf('.');\r
-                            if (iDot > 0) {\r
-                                str = str.substring(0, iDot);\r
-                            }\r
-                            magvar.setTextContent(str);\r
-                            ret.appendChild(magvar);\r
-                            \r
-                            Element speed = ret.getOwnerDocument().createElement("speed");\r
-                            str = Double.toString(Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));\r
-                            iDot = str.indexOf('.');\r
-                            if (iDot > 0) {\r
-                                str = str.substring(0, iDot);\r
-                            }\r
-                            speed.setTextContent(str);\r
-                            ret.appendChild(speed);\r
-                        }\r
+                if (mae != null) {\r
+                       Complementation obj = new Complementation(ret, mae);\r
+\r
+                    // 経度(longitude)と経度から進行方向を求める\r
+                    if ((magvar == null) || param_GpxOverwriteMagvar) {\r
+                       obj.complementationMagvar(ret);\r
                     }\r
+\r
+                    // 緯度・経度と時間差から速度(m/sec)を求める\r
+                       obj.complementationSpeed(ret);\r
+                       \r
+                       magvar = obj.magvar;\r
                 }\r
             }\r
             mae = map.get(time);\r
@@ -803,6 +752,7 @@ public class ImportPicture extends Thread {
         return null;\r
     }\r
 \r
+\r
     /**\r
      * 対象は '*.JPG' のみ対象とする\r
      * @return \r
@@ -895,6 +845,19 @@ public class ImportPicture extends Thread {
                     }\r
                 }\r
                 break;\r
+            case "speed":\r
+                for (int i2=0; i2 < nodes2.getLength(); i2++) {\r
+                    Node node2 = nodes2.item(i2);\r
+                    if (node2 != null) {\r
+                        if (node2.getNodeType() == Node.TEXT_NODE) {\r
+                            String speedStr = node2.getNodeValue();\r
+                            Element speedE = document.createElement("speed");\r
+                            speedE.setTextContent(speedStr);\r
+                            wpt.appendChild(speedE);\r
+                        }\r
+                    }\r
+                }\r
+                break;\r
             }\r
         }\r
 \r