| |
---|
| | </link> |
---|
| | <sat>9</sat> |
---|
| | </wpt> |
---|
| | */ |
---|
| | DocumentBuilderFactory factory; |
---|
| | DocumentBuilder builder; |
---|
| | Node gpx; |
---|
| | |
---|
| | try { |
---|
| | if (params.getProperty(AppParameters.IMG_OUTPUT).equals(Boolean.toString(true))) { |
---|
| | outDir = new File(outDir, imgDir.getName()); |
---|
| | } |
---|
| |
---|
| | outDir = gpxDir; |
---|
| | } |
---|
| | |
---|
| | 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); |
---|
| | |
---|
| | /* |
---|
| | * <gpx> |
---|
| | * <trk> |
---|
| | * <name><![CDATA[Tracked with OSMTracker for Android?]]></name> |
---|
| | * <cmt><![CDATA[警告: HDOP values aren't the HDOP as returned by the GPS device. They're approximated from the location accuracy in meters.]]></cmt> |
---|
| | * <trkseg> |
---|
| | * <trkpt lat="35.32123832" lon="139.56965631"> |
---|
| | * <ele>47.20000076293945</ele> |
---|
| | * <time>2012-06-15T03:00:29Z</time> |
---|
| | * <hdop>0.5</hdop> |
---|
| | * </trkpt> |
---|
| | * </trkseg> |
---|
| | * </trk> |
---|
| | * <wpt lat="35.2564461" lon="139.15437809"></wpt> |
---|
| | * </gpx> |
---|
| | */ |
---|
| | TreeMap<Long,Element> map = new TreeMap<>(); |
---|
| | TreeMap<Long,Element> 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>から<trkseg>を削除する。 |
---|
| | trk.removeChild(nodeTRKSEG); |
---|
| | 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); |
---|
| | |
---|
| | /* |
---|
| | * <gpx> |
---|
| | * <trk> |
---|
| | * <name><![CDATA[Tracked with OSMTracker for Android?]]></name> |
---|
| | * <cmt><![CDATA[警告: HDOP values aren't the HDOP as returned by the GPS device. They're approximated from the location accuracy in meters.]]></cmt> |
---|
| | * <trkseg> |
---|
| | * <trkpt lat="35.32123832" lon="139.56965631"> |
---|
| | * <ele>47.20000076293945</ele> |
---|
| | * <time>2012-06-15T03:00:29Z</time> |
---|
| | * <hdop>0.5</hdop> |
---|
| | * </trkpt> |
---|
| | * </trkseg> |
---|
| | * </trk> |
---|
| | * <wpt lat="35.2564461" lon="139.15437809"></wpt> |
---|
| | * </gpx> |
---|
| | */ |
---|
| | TreeMap<Long,Element> map = new TreeMap<>(); |
---|
| | TreeMap<Long,Element> 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)); |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | // <trkseg>毎に実行する |
---|
| | Iterator<Long> keyIte = mapTRKSEG.keySet().iterator(); |
---|
| | while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得 |
---|
| | |
---|
| | // <trk>に、新たな<trkseg>を追加する。 |
---|
| | Element newTRKSEG = mapTRKSEG.get(keyIte.next()); |
---|
| | trk.appendChild(newTRKSEG); |
---|
| | |
---|
| | // mapに、<trkpy>を割り付ける |
---|
| | trkptMap(newTRKSEG, map); |
---|
| | } |
---|
| | mapTRKSEG.put(new Long(trksegCounter), getCopy(doc, newTRKSEG)); |
---|
| | |
---|
| | // <trk>から<trkseg>を削除する。 |
---|
| | trk.removeChild(nodeTRKSEG); |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | /* |
---|
| | * GPXへ割りつける開始時刻と終了時刻を求める |
---|
| | */ |
---|
| | long gpxStartTime = (new Date()).getTime(); // 対象とする開始時刻(現在時刻) |
---|
| | long gpxEndTime = 0L; // 対象とする終了時刻 |
---|
| | Set<Long> 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); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | catch(ParserConfigurationException | DOMException | SAXException | IOException | ParseException | ImageReadException | ImageWriteException | IllegalArgumentException | TransformerException e) { |
---|
| | } |
---|
| | } |
---|
| | // <trkseg>毎に実行する |
---|
| | Iterator<Long> keyIte = mapTRKSEG.keySet().iterator(); |
---|
| | while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得 |
---|
| | |
---|
| | // <trk>に、新たな<trkseg>を追加する。 |
---|
| | Element newTRKSEG = mapTRKSEG.get(keyIte.next()); |
---|
| | trk.appendChild(newTRKSEG); |
---|
| | |
---|
| | // mapに、<trkpy>を割り付ける |
---|
| | trkptMap(newTRKSEG, map); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | /* |
---|
| | * GPXへ割りつける開始時刻と終了時刻を求める |
---|
| | */ |
---|
| | long gpxStartTime = (new Date()).getTime(); // 対象とする開始時刻(現在時刻) |
---|
| | long gpxEndTime = 0L; // 対象とする終了時刻 |
---|
| | Set<Long> 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); |
---|
| | |
---|
| | } |
---|
| | |
---|
| | |
---|
| | /** |
---|
| | * 再帰メソッド |
---|
| | * @throws ParseException |
---|
| |
---|
| | double longitude = Double.parseDouble(lonStr); |
---|
| | |
---|
| | String eleStr = "-"; |
---|
| | String magvarStr = "-"; |
---|
| | String speedStr = "-"; |
---|
| | NodeList nodes = wpt.getChildNodes(); // 子ノードを取得 |
---|
| | for (int i4 = 0; i4 < nodes.getLength(); i4++) { |
---|
| | Node node = nodes.item(i4); |
---|
| | if (node != null) { |
---|
| |
---|
| | break; |
---|
| | 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) { |
---|
| | TiffOutputSet outputSet = null; |
---|
| |
---|
| | * @param jptime 画像ファイルの撮影日時 ミリ秒(日本時間) |
---|
| | * @throws ParseException |
---|
| | */ |
---|
| | public Element trkpt(TreeMap<Long,Element> map, Date jptime) throws ParseException { |
---|
| | Double R = 20000000 / Math.PI; |
---|
| | long sa = 2L * 3600000L; |
---|
| | long jpt = jptime.getTime(); |
---|
| | Element ret = null; |
---|
| | Element mae = null; |
---|
| |
---|
| | Iterator<Long> keyIte = keySet.iterator(); |
---|
| | 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); |
---|
| | |
---|
| | // <MAGVAR>がなければ、 |
---|
| | // 直前の位置と、現在地から進行方向を求める |
---|
| | 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; |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | 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); |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | if (mae != null) { |
---|
| | Complementation obj = new Complementation(ret, mae); |
---|
| | |
---|
| | // 経度(longitude)と経度から進行方向を求める |
---|
| | if ((magvar == null) || param_GpxOverwriteMagvar) { |
---|
| | obj.complementationMagvar(ret); |
---|
| | } |
---|
| | |
---|
| | // 緯度・経度と時間差から速度(m/sec)を求める |
---|
| | obj.complementationSpeed(ret); |
---|
| | |
---|
| | magvar = obj.magvar; |
---|
| | } |
---|
| | } |
---|
| | mae = map.get(time); |
---|
| | } |
---|
| |
---|
| | return ret; |
---|
| | } |
---|
| | return null; |
---|
| | } |
---|
| | |
---|
| | |
---|
| | /** |
---|
| | * 対象は '*.JPG' のみ対象とする |
---|
| | * @return |
---|
| |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | 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; |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | Element name = document.createElement("name"); |
---|
| |
---|
| | |