diff --git a/importPicture/src/osm/jp/gpx/Complementation.java b/importPicture/src/osm/jp/gpx/Complementation.java new file mode 100644 index 0000000..7b1914f --- /dev/null +++ b/importPicture/src/osm/jp/gpx/Complementation.java @@ -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 { + // がなければ、 + // 直前の位置と、現在地から進行方向を求める + 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; + } + +} diff --git a/importPicture/src/osm/jp/gpx/ImportPicture.java b/importPicture/src/osm/jp/gpx/ImportPicture.java index f37aa2d..03ed192 100644 --- a/importPicture/src/osm/jp/gpx/ImportPicture.java +++ b/importPicture/src/osm/jp/gpx/ImportPicture.java @@ -276,10 +276,6 @@ 9 */ - DocumentBuilderFactory factory; - DocumentBuilder builder; - Node gpx; - try { if (params.getProperty(AppParameters.IMG_OUTPUT).equals(Boolean.toString(true))) { outDir = new File(outDir, imgDir.getName()); @@ -289,136 +285,156 @@ } for (File gpxFile : this.gpxFiles) { - String fileName = gpxFile.getName(); - String iStr = fileName.substring(0, fileName.length() - 4); - - File outputFile = new File(outDir, iStr +"_.gpx"); - System.out.println(gpxFile.getAbsolutePath() + " => "+ outputFile.getAbsolutePath()); - System.out.println(" 時差: "+ (delta / 1000) +"(sec)"); - System.out.println(" Target GPX: ["+ gpxFile.getAbsolutePath() +"]"); - System.out.println(" EXIF: "+ (exif ? ("convert to '" + outDir.getAbsolutePath() +"'") : "off")); - System.out.println(); - - factory = DocumentBuilderFactory.newInstance(); - builder = factory.newDocumentBuilder(); - factory.setIgnoringElementContentWhitespace(true); - factory.setIgnoringComments(true); - factory.setValidating(true); - - // GPX file --> Node root - DOMImplementation domImpl = builder.getDOMImplementation(); - document = domImpl.createDocument("", "gpx", null); - - /* - * - * - * - * - * - * - * 47.20000076293945 - * - * 0.5 - * - * - * - * - * - */ - TreeMap map = new TreeMap<>(); - TreeMap mapTRKSEG = new TreeMap<>(); - Element trk = null; - gpx = builder.parse(gpxFile).getFirstChild(); - Document doc = gpx.getOwnerDocument(); - NodeList nodes = gpx.getChildNodes(); - for (int i=0; i < nodes.getLength(); i++) { - Node node2 = nodes.item(i); - if (node2.getNodeName().equals("trk")) { - trk = (Element) node2; - - NodeList nodes1 = trk.getChildNodes(); - int trksegCounter = 0; - for (int i1=0; i1 < nodes1.getLength(); i1++) { - Node nodeTRKSEG = nodes1.item(i1); - if (nodeTRKSEG.getNodeName().equals("trkseg")) { - trksegCounter++; - Element newTRKSEG = doc.createElement("trkseg"); - Element trkseg = (Element) nodeTRKSEG; - NodeList nodes2 = trkseg.getChildNodes(); - for (int i2=0; i2 < nodes2.getLength(); i2++) { - Node nodeTRKPT = nodes2.item(i2); - if (nodeTRKPT.getNodeName().equals("trkpt")) { - if (param_GpxNoFirstNode && (i2 == 0)) { - continue; - } - newTRKSEG.appendChild(getCopy(doc, nodeTRKPT)); - } - } - mapTRKSEG.put(new Long(trksegCounter), getCopy(doc, newTRKSEG)); - - // からを削除する。 - trk.removeChild(nodeTRKSEG); - } - } - - // 毎に実行する - Iterator keyIte = mapTRKSEG.keySet().iterator(); - while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得 - - // に、新たなを追加する。 - Element newTRKSEG = mapTRKSEG.get(keyIte.next()); - trk.appendChild(newTRKSEG); - - // mapに、を割り付ける - trkptMap(newTRKSEG, map); - } - } - } - - /* - * GPXへ割りつける開始時刻と終了時刻を求める - */ - long gpxStartTime = (new Date()).getTime(); // 対象とする開始時刻(現在時刻) - long gpxEndTime = 0L; // 対象とする終了時刻 - Set keySet = map.keySet(); //すべてのキー値を取得 - for (Long timeLong : keySet) { - long gpxTime = timeLong; - if (gpxStartTime > gpxTime) { - gpxStartTime = gpxTime; - } - if (gpxEndTime < gpxTime) { - gpxEndTime = gpxTime; - } - } - - System.out.println("GPX start time: "+ dfjp.format(new Date(gpxStartTime)) + "\t[GMT " + dfuk.format(new Date(gpxStartTime))+"]"); - System.out.println(" GPX end time: "+ dfjp.format(new Date(gpxEndTime)) + "\t[GMT " + dfuk.format(new Date(gpxEndTime))+"]"); - System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|"); - System.out.println(" name | UpdateTime | GPStime | Latitude | Longitude | ele |magvar|"); - System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|"); - proc(imgDir, delta, gpxStartTime, gpxEndTime, map, exif, gpx); - System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|"); - - // 出力 - DOMSource source = new DOMSource(gpx); - FileOutputStream os = new FileOutputStream(outputFile); - StreamResult result = new StreamResult(os); - TransformerFactory transFactory = TransformerFactory.newInstance(); - Transformer transformer = transFactory.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty(OutputKeys.METHOD, "xml"); - transformer.transform(source, result); - if (exif) { - outputFile = new File(outDir, iStr +"_.gpx"); - os = new FileOutputStream(outputFile); - result = new StreamResult(os); - transformer.transform(source, result); - } + procGPXfile(gpxFile); } } catch(ParserConfigurationException | DOMException | SAXException | IOException | ParseException | ImageReadException | ImageWriteException | IllegalArgumentException | TransformerException e) { } } + + /** + * 個別のGPXファイルを処理する + * + * @throws ParserConfigurationException + * @throws IOException + * @throws SAXException + * @throws ParseException + * @throws ImageWriteException + * @throws ImageReadException + * @throws TransformerException + */ + void procGPXfile(File gpxFile) throws ParserConfigurationException, SAXException, IOException, ParseException, ImageReadException, ImageWriteException, TransformerException { + DocumentBuilderFactory factory; + DocumentBuilder builder; + Node gpx; + + String fileName = gpxFile.getName(); + String iStr = fileName.substring(0, fileName.length() - 4); + + File outputFile = new File(outDir, iStr +"_.gpx"); + System.out.println(gpxFile.getAbsolutePath() + " => "+ outputFile.getAbsolutePath()); + System.out.println(" 時差: "+ (delta / 1000) +"(sec)"); + System.out.println(" Target GPX: ["+ gpxFile.getAbsolutePath() +"]"); + System.out.println(" EXIF: "+ (exif ? ("convert to '" + outDir.getAbsolutePath() +"'") : "off")); + System.out.println(); + + factory = DocumentBuilderFactory.newInstance(); + builder = factory.newDocumentBuilder(); + factory.setIgnoringElementContentWhitespace(true); + factory.setIgnoringComments(true); + factory.setValidating(true); + + // GPX file --> Node root + DOMImplementation domImpl = builder.getDOMImplementation(); + document = domImpl.createDocument("", "gpx", null); + + /* + * + * + * + * + * + * + * 47.20000076293945 + * + * 0.5 + * + * + * + * + * + */ + TreeMap map = new TreeMap<>(); + TreeMap mapTRKSEG = new TreeMap<>(); + Element trk = null; + gpx = builder.parse(gpxFile).getFirstChild(); + Document doc = gpx.getOwnerDocument(); + NodeList nodes = gpx.getChildNodes(); + for (int i=0; i < nodes.getLength(); i++) { + Node node2 = nodes.item(i); + if (node2.getNodeName().equals("trk")) { + trk = (Element) node2; + + NodeList nodes1 = trk.getChildNodes(); + int trksegCounter = 0; + for (int i1=0; i1 < nodes1.getLength(); i1++) { + Node nodeTRKSEG = nodes1.item(i1); + if (nodeTRKSEG.getNodeName().equals("trkseg")) { + trksegCounter++; + Element newTRKSEG = doc.createElement("trkseg"); + Element trkseg = (Element) nodeTRKSEG; + NodeList nodes2 = trkseg.getChildNodes(); + for (int i2=0; i2 < nodes2.getLength(); i2++) { + Node nodeTRKPT = nodes2.item(i2); + if (nodeTRKPT.getNodeName().equals("trkpt")) { + if (param_GpxNoFirstNode && (i2 == 0)) { + continue; + } + newTRKSEG.appendChild(getCopy(doc, nodeTRKPT)); + } + } + mapTRKSEG.put(new Long(trksegCounter), getCopy(doc, newTRKSEG)); + + // からを削除する。 + trk.removeChild(nodeTRKSEG); + } + } + + // 毎に実行する + Iterator keyIte = mapTRKSEG.keySet().iterator(); + while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得 + + // に、新たなを追加する。 + Element newTRKSEG = mapTRKSEG.get(keyIte.next()); + trk.appendChild(newTRKSEG); + + // mapに、を割り付ける + trkptMap(newTRKSEG, map); + } + } + } + + /* + * GPXへ割りつける開始時刻と終了時刻を求める + */ + long gpxStartTime = (new Date()).getTime(); // 対象とする開始時刻(現在時刻) + long gpxEndTime = 0L; // 対象とする終了時刻 + Set keySet = map.keySet(); //すべてのキー値を取得 + for (Long timeLong : keySet) { + long gpxTime = timeLong; + if (gpxStartTime > gpxTime) { + gpxStartTime = gpxTime; + } + if (gpxEndTime < gpxTime) { + gpxEndTime = gpxTime; + } + } + + System.out.println("GPX start time: "+ dfjp.format(new Date(gpxStartTime)) + "\t[GMT " + dfuk.format(new Date(gpxStartTime))+"]"); + System.out.println(" GPX end time: "+ dfjp.format(new Date(gpxEndTime)) + "\t[GMT " + dfuk.format(new Date(gpxEndTime))+"]"); + System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|------|"); + System.out.println(" name | UpdateTime | GPStime | Latitude | Longitude | ele |magvar| speed|"); + System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|------|"); + proc(imgDir, delta, gpxStartTime, gpxEndTime, map, exif, gpx); + System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|------|"); + + // 出力 + DOMSource source = new DOMSource(gpx); + FileOutputStream os = new FileOutputStream(outputFile); + StreamResult result = new StreamResult(os); + TransformerFactory transFactory = TransformerFactory.newInstance(); + Transformer transformer = transFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + transformer.transform(source, result); + + outputFile = new File(outDir, iStr +"_.gpx"); + os = new FileOutputStream(outputFile); + result = new StreamResult(os); + transformer.transform(source, result); + + } + /** * 再帰メソッド @@ -488,6 +504,7 @@ String eleStr = "-"; String magvarStr = "-"; + String speedStr = "-"; NodeList nodes = wpt.getChildNodes(); // 子ノードを取得 for (int i4 = 0; i4 < nodes.getLength(); i4++) { Node node = nodes.item(i4); @@ -499,12 +516,15 @@ case "magvar": magvarStr = node.getFirstChild().getNodeValue(); break; + case "speed": + speedStr = node.getFirstChild().getNodeValue(); + break; } } } System.out.print(String.format("%12s %12s|", latStr, lonStr)); - System.out.println(String.format("%8s|%6s|", eleStr, magvarStr)); + System.out.println(String.format("%8s|%6s|%6s|", eleStr, magvarStr, speedStr)); ret = true; if (exifWrite) { @@ -689,7 +709,6 @@ * @throws ParseException */ public Element trkpt(TreeMap map, Date jptime) throws ParseException { - Double R = 20000000 / Math.PI; long sa = 2L * 3600000L; long jpt = jptime.getTime(); Element ret = null; @@ -700,97 +719,27 @@ while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得 Long time = keyIte.next(); long t = time; + if (Math.abs(jpt - t) < sa) { sa = Math.abs(jpt - t); ret = map.get(time); // がなければ、 // 直前の位置と、現在地から進行方向を求める - NodeList nodes3 = ret.getChildNodes(); Element magvar = null; - for (int i3=0; i3 < nodes3.getLength(); i3++) { - Node node4 = nodes3.item(i3); - if (node4.getNodeName().toLowerCase().equals("magvar")) { - magvar = (Element) node4; - break; - } - } - if ((magvar == null) || param_GpxOverwriteMagvar) { - if (mae != null) { - Double maeLAT = null; - Double maeLON = null; - Double imaLAT = null; - Double imaLON =null; - // 経度(longitude)と経度から進行方向を求める - NamedNodeMap nodeMap = mae.getAttributes(); - if (null != nodeMap) { - 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; - } - } - nodeMap = ret.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; - } - } - 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; - } - } + if (mae != null) { + Complementation obj = new Complementation(ret, mae); - magvar = ret.getOwnerDocument().createElement("magvar"); - String str = Double.toString(rad); - int iDot = str.indexOf('.'); - if (iDot > 0) { - str = str.substring(0, iDot); - } - magvar.setTextContent(str); - ret.appendChild(magvar); - - Element speed = ret.getOwnerDocument().createElement("speed"); - str = Double.toString(Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))); - iDot = str.indexOf('.'); - if (iDot > 0) { - str = str.substring(0, iDot); - } - speed.setTextContent(str); - ret.appendChild(speed); - } + // 経度(longitude)と経度から進行方向を求める + if ((magvar == null) || param_GpxOverwriteMagvar) { + obj.complementationMagvar(ret); } + + // 緯度・経度と時間差から速度(m/sec)を求める + obj.complementationSpeed(ret); + + magvar = obj.magvar; } } mae = map.get(time); @@ -803,6 +752,7 @@ return null; } + /** * 対象は '*.JPG' のみ対象とする * @return @@ -895,6 +845,19 @@ } } break; + case "speed": + for (int i2=0; i2 < nodes2.getLength(); i2++) { + Node node2 = nodes2.item(i2); + if (node2 != null) { + if (node2.getNodeType() == Node.TEXT_NODE) { + String speedStr = node2.getNodeValue(); + Element speedE = document.createElement("speed"); + speedE.setTextContent(speedStr); + wpt.appendChild(speedE); + } + } + } + break; } }