import java.util.Comparator;\r
import java.util.Date;\r
import java.util.GregorianCalendar;\r
-import java.util.HashMap;\r
import java.util.Iterator;\r
import java.util.Set;\r
import java.util.TimeZone;\r
+import java.util.TreeMap;\r
import java.util.logging.LogManager;\r
import java.util.logging.Logger;\r
\r
import javax.xml.parsers.*;\r
import javax.xml.transform.OutputKeys;\r
import javax.xml.transform.Transformer;\r
+import javax.xml.transform.TransformerException;\r
import javax.xml.transform.TransformerFactory;\r
import javax.xml.transform.dom.DOMSource;\r
import javax.xml.transform.stream.StreamResult;\r
import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;\r
import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;\r
import org.w3c.dom.*;\r
+import org.xml.sax.SAXException;\r
+\r
+public class ImportPicture extends Thread {\r
+ /**\r
+ * ログ設定プロパティファイルのファイル内容\r
+ */\r
+ protected static final String LOGGING_PROPERTIES_DATA\r
+ = "handlers=java.util.logging.ConsoleHandler\n"\r
+ + ".level=FINEST\n"\r
+ + "java.util.logging.ConsoleHandler.level=INFO\n"\r
+ + "java.util.logging.ConsoleHandler.formatter=osm.jp.gpx.YuuLogFormatter";\r
\r
-public class ImportPicture {\r
- public static File gpxDir = new File(".");\r
- public static File outDir = null;\r
- \r
/**\r
- * ログ設定プロパティファイルのファイル内容\r
- */\r
- protected static final String LOGGING_PROPERTIES_DATA\r
- = "handlers=java.util.logging.ConsoleHandler\n"\r
- + ".level=FINEST\n"\r
- + "java.util.logging.ConsoleHandler.level=INFO\n"\r
- + "java.util.logging.ConsoleHandler.formatter=osm.jp.gpx.YuuLogFormatter";\r
-\r
- /**\r
- * static initializer によるログ設定の初期化\r
- */\r
+ * static initializer によるログ設定の初期化\r
+ */\r
public static final Logger logger = Logger.getLogger("CommandLogging");\r
static {\r
InputStream inStream = null;\r
finally {\r
try {\r
if (inStream != null) {\r
- inStream.close();\r
+ inStream.close();\r
}\r
} catch (IOException e) {\r
logger.warning("ログ設定: ログ設定プロパティファイルのストリームクローズ時に例外が発生しました。:"+ e.toString());\r
* argv[0] = 画像ファイルが格納されているディレクトリ\r
* argv[1] = 時刻補正の基準とする画像ファイル\r
* argv[2] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd'T'HH:mm:ss"\r
- * argv[3] = [EXIF] EXIF情報の書き換えを行う / [not] EXIF情報の書き換えを行わない\r
+ * argv[3] = [noEXIF] EXIF情報の書き換えを行わない / EXIF情報の書き換えを行う(出力先フォルダ)\r
* argv[4] = 撮影位置をロギングしたGPXファイル\r
* \r
* @throws IOException\r
{\r
Date jptime;\r
\r
+ ImportPicture obj = new ImportPicture();\r
+\r
if (argv.length > 0) {\r
- gpxDir = new File(argv[0]);\r
+ obj.imgDir = new File(argv[0]);\r
}\r
\r
if (argv.length < 4) {\r
}\r
\r
// 基準時刻ファイルの「更新日時」を使って時刻合わせを行う。\r
- File baseFile = new File(gpxDir, argv[1]);\r
+ File baseFile = new File(obj.imgDir, argv[1]);\r
jptime = new Date(baseFile.lastModified());\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
+ }\r
\r
// \r
- boolean exif = false;\r
- if (argv[3].toUpperCase().equals("EXIF")) {\r
- exif = true;\r
+ if (argv[3].toUpperCase().equals("noEXIF")) {\r
+ obj.exif = false;\r
+ obj.outDir = null;\r
+ }\r
+ else {\r
+ obj.exif = true;\r
+ obj.outDir = new File(argv[3]);\r
}\r
\r
// 第6引数が指定されなければ、指定されたディレクトリ内のGPXファイルすべてを対象とする\r
- ArrayList<File> gpxFiles = new ArrayList<>();\r
- if (argv.length > 4) {\r
- gpxFiles.add(new File(gpxDir, argv[4]));\r
+ if (argv.length >= 5) {\r
+ obj.gpxDir = new File(argv[4]);\r
+ }\r
+ else {\r
+ obj.gpxDir = obj.imgDir;\r
+ }\r
+ if (obj.gpxDir.isFile()) {\r
+ obj.gpxFiles.add(new File(obj.gpxDir, argv[4])); \r
}\r
else {\r
- File[] files = gpxDir.listFiles();\r
+ File[] files = obj.gpxDir.listFiles();\r
for (File file : files) {\r
if (file.isFile()) {\r
String filename = file.getName().toUpperCase();\r
if (filename.endsWith(".GPX")) {\r
if (!filename.endsWith("_.GPX")) {\r
- gpxFiles.add(file);\r
+ obj.gpxFiles.add(file);\r
}\r
}\r
}\r
}\r
}\r
-\r
-\r
+ \r
+ obj.start();\r
+ try {\r
+ obj.join(); \r
+ } catch(InterruptedException end) {}\r
+ }\r
+ \r
+ public File gpxDir;\r
+ public File imgDir;\r
+ public File outDir;\r
+ public long delta = 0;\r
+ public boolean exif = false;\r
+ public ArrayList<File> gpxFiles = new ArrayList<>();\r
+ \r
+ @Override\r
+ public void run() {\r
+ \r
/**\r
*\r
<wpt lat="35.25714922" lon="139.15490497">\r
DocumentBuilder builder;\r
Node gpx;\r
\r
- for (File gpxFile : gpxFiles) {\r
- String fileName = gpxFile.getName();\r
- String iStr = fileName.substring(0, fileName.length() - 4);\r
-\r
- File outputFile = new File(gpxFile.getParent(), iStr +"_.gpx");\r
- System.out.println(iStr + " => "+ outputFile.getName());\r
-\r
- factory = DocumentBuilderFactory.newInstance();\r
- builder = factory.newDocumentBuilder();\r
- factory.setIgnoringElementContentWhitespace(true);\r
- factory.setIgnoringComments(true);\r
- factory.setValidating(true);\r
-\r
- // GPX file --> Node root\r
- DOMImplementation domImpl = builder.getDOMImplementation();\r
- document = domImpl.createDocument("", "gpx", null);\r
-\r
- /*\r
- <gpx>\r
- <trk>\r
- <name><![CDATA[Tracked with OSMTracker for Android?]]></name>\r
- <cmt><![CDATA[警告: HDOP values aren't the HDOP as returned by the GPS device. They're approximated from the location accuracy in meters.]]></cmt>\r
- <trkseg>\r
- <trkpt lat="35.32123832" lon="139.56965631">\r
- <ele>47.20000076293945</ele>\r
- <time>2012-06-15T03:00:29Z</time>\r
- <hdop>0.5</hdop>\r
- </trkpt>\r
- </trkseg>\r
- </trk>\r
- <wpt lat="35.2564461" lon="139.15437809">\r
- </wpt>\r
- </gpx>\r
- */\r
- HashMap<Long,Element> map = new HashMap<>();\r
- Element trk = null;\r
- gpx = builder.parse(gpxFile).getFirstChild();\r
- NodeList nodes = gpx.getChildNodes();\r
- for (int i=0; i < nodes.getLength(); i++) {\r
- Node node2 = nodes.item(i);\r
- if (node2.getNodeName().equals("trk")) {\r
- trk = (Element) node2;\r
- trkptMap(trk, map);\r
+ try {\r
+ outDir = new File(outDir, imgDir.getName());\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(imgDir, iStr +"_.gpx");\r
+ System.out.println(iStr + " => "+ outputFile.getName());\r
+\r
+ factory = DocumentBuilderFactory.newInstance();\r
+ builder = factory.newDocumentBuilder();\r
+ factory.setIgnoringElementContentWhitespace(true);\r
+ factory.setIgnoringComments(true);\r
+ factory.setValidating(true);\r
+\r
+ // GPX file --> Node root\r
+ DOMImplementation domImpl = builder.getDOMImplementation();\r
+ document = domImpl.createDocument("", "gpx", null);\r
+\r
+ /*\r
+ <gpx>\r
+ <trk>\r
+ <name><![CDATA[Tracked with OSMTracker for Android?]]></name>\r
+ <cmt><![CDATA[警告: HDOP values aren't the HDOP as returned by the GPS device. They're approximated from the location accuracy in meters.]]></cmt>\r
+ <trkseg>\r
+ <trkpt lat="35.32123832" lon="139.56965631">\r
+ <ele>47.20000076293945</ele>\r
+ <time>2012-06-15T03:00:29Z</time>\r
+ <hdop>0.5</hdop>\r
+ </trkpt>\r
+ </trkseg>\r
+ </trk>\r
+ <wpt lat="35.2564461" lon="139.15437809">\r
+ </wpt>\r
+ </gpx>\r
+ */\r
+ TreeMap<Long,Element> map = new TreeMap<>();\r
+ Element trk = null;\r
+ gpx = builder.parse(gpxFile).getFirstChild();\r
+ NodeList nodes = gpx.getChildNodes();\r
+ for (int i=0; i < nodes.getLength(); i++) {\r
+ Node node2 = nodes.item(i);\r
+ if (node2.getNodeName().equals("trk")) {\r
+ trk = (Element) node2;\r
+ trkptMap(trk, map);\r
+ }\r
}\r
- }\r
-\r
- if (trk != null) {\r
- dfjp.setTimeZone(TimeZone.getTimeZone("JST"));\r
- String timeStr = argv[2];\r
- try {\r
- Date t = dfjp.parse(timeStr);\r
- long delta = t.getTime() - jptime.getTime();\r
\r
+ boolean change = false;\r
+ if (trk != null) {\r
/*\r
* GPXへ割りつける開始時刻と終了時刻を求める\r
*/\r
}\r
\r
System.out.println(" 時差: "+ (delta / 1000) +"(sec)");\r
- System.out.println(" Target GPX: ["+ gpxFile.getName() +"]");\r
+ System.out.println(" Target GPX: ["+ gpxFile.getAbsolutePath() +"]");\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(" EXIF: "+ (exif ? ("convert to '" + outDir.getAbsolutePath() +"'") : "off"));\r
System.out.println();\r
System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
System.out.println(" name | UpdateTime | GPStime | Latitude | Longitude | ele |magvar|");\r
System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
- proc(gpxDir, delta, gpxStartTime, gpxEndTime, map, exif, gpx);\r
+ change = proc(imgDir, delta, gpxStartTime, gpxEndTime, map, exif, gpx);\r
System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");\r
}\r
- catch (ParseException e) {\r
- System.out.println("'"+ timeStr +"' の書式が違います("+ TIME_FORMAT_STRING +")");\r
+\r
+ // 出力\r
+ if (change) {\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
+ }\r
}\r
}\r
-\r
- // 出力\r
- DOMSource source = new DOMSource(gpx);\r
- FileOutputStream os = new FileOutputStream(outputFile);\r
- StreamResult result = new StreamResult(os);\r
- TransformerFactory transFactory = TransformerFactory.newInstance();\r
- Transformer transformer = transFactory.newTransformer();\r
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
- transformer.setOutputProperty(OutputKeys.METHOD, "xml");\r
- transformer.transform(source, result);\r
+ }\r
+ catch(ParserConfigurationException | DOMException | SAXException | IOException | ParseException | ImageReadException | ImageWriteException | IllegalArgumentException | TransformerException e) {\r
}\r
}\r
\r
* @throws ImageReadException \r
* @throws ImageWriteException \r
*/\r
- static void proc(File dir, long delta, long gpxStartTime, long gpxEndTime, HashMap<Long,Element> map, boolean exifWrite, Node gpx) throws ParseException, ImageReadException, IOException, ImageWriteException {\r
+ 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 ret = false;\r
File[] files = dir.listFiles();\r
Arrays.sort(files, new FileSort());\r
for (File image : files) {\r
if (image.isDirectory()) {\r
- proc(image, delta, gpxStartTime, gpxEndTime, map, exifWrite, gpx);\r
+ ret = proc(image, delta, gpxStartTime, gpxEndTime, map, exifWrite, gpx);\r
}\r
else {\r
String imageName = image.getName();\r
if ((uktime.getTime() >= gpxStartTime) && (uktime.getTime() <= gpxEndTime)) {\r
Element trkpt = trkpt(map, uktime);\r
if (trkpt != null) {\r
- System.out.print(String.format("%12s|", image.getName()));\r
- System.out.print(String.format("%20s ", dfjp.format(itime)));\r
- System.out.print(String.format("%20s|", dfjp.format(uktime)));\r
-\r
Element wpt = createWptTag(image, uktime.getTime(), trkpt);\r
String latStr = wpt.getAttribute("lat");\r
String lonStr = wpt.getAttribute("lon");\r
- System.out.print(String.format("%12s %12s|", latStr, lonStr));\r
double latitude = Double.parseDouble(latStr);\r
double longitude = Double.parseDouble(lonStr);\r
-\r
+ \r
String eleStr = "-";\r
String magvarStr = "-";\r
NodeList nodes = wpt.getChildNodes(); // 子ノードを取得\r
}\r
}\r
}\r
+\r
+ System.out.print(String.format("%12s|", image.getName()));\r
+ System.out.print(String.format("%20s ", dfjp.format(itime)));\r
+ System.out.print(String.format("%20s|", dfjp.format(uktime)));\r
+ System.out.print(String.format("%12s %12s|", latStr, lonStr));\r
System.out.println(String.format("%8s|%6s|", eleStr, magvarStr));\r
+ ret = true;\r
\r
if (exifWrite) {\r
TiffOutputSet outputSet = null;\r
RationalNumber.valueOf(latitudeSeconds));\r
}\r
\r
+ outDir.mkdir();\r
ExifRewriter rewriter = new ExifRewriter();\r
try {\r
- if (outDir == null) {\r
- outDir = new File(dir, "converted");\r
- outDir.mkdir();\r
- }\r
fos = new FileOutputStream(new File(outDir, imageName));\r
rewriter.updateExifMetadataLossy(image, fos, outputSet);\r
}\r
}\r
}\r
}\r
+ return ret;\r
}\r
\r
static Document document;\r
* @param map\r
* @throws ParseException\r
*/\r
- public static void trkptMap(Element trk, HashMap<Long,Element> map) throws ParseException {\r
+ public static void trkptMap(Element trk, TreeMap<Long,Element> map) throws ParseException {\r
dfuk.setTimeZone(TimeZone.getTimeZone("GMT"));\r
\r
NodeList nodes1 = trk.getChildNodes();\r
* @param jptime\r
* @throws ParseException\r
*/\r
- public static Element trkpt(HashMap<Long,Element> map, Date jptime) throws ParseException {\r
- Double R = 20000000 / Math.PI; // 地球の半径(m)\r
+ public static 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
break;\r
}\r
}\r
- Double dLON = imaLON - maeLON;\r
- Double dLAT = imaLAT - maeLAT;\r
- Double r = Math.cos(Math.toRadians((imaLAT + maeLAT) * 2)) * R;\r
+ Double r = Math.cos(Math.toRadians((imaLAT + maeLAT) / 2)) * R;\r
Double x = Math.toRadians(imaLON - maeLON) * r;\r
Double y = Math.toRadians(imaLAT - maeLAT) * R;\r
- double rad = Math.toDegrees(Math.atan(y / x));\r
+ double rad = Math.toDegrees(Math.atan2(y, x));\r
\r
- if (y < 0) {\r
- rad = rad * -1;\r
- if (x > 0) {\r
- rad = rad + 90;\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 = rad - 90;\r
+ rad = 90 - rad;\r
}\r
}\r
\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
}\r
}\r
* @param timestamp\r
* @param trkpt\r
*/\r
- public static Element createWptTag(File iFile, long timestamp, Element trkpt) {\r
+ public Element createWptTag(File iFile, long timestamp, Element trkpt) {\r
Element wpt = document.createElement("wpt");\r
\r
NamedNodeMap nodeMap = trkpt.getAttributes();\r
wpt.appendChild(name);\r
\r
Element link = document.createElement("link");\r
- link.setAttribute("href", getShortPathName(gpxDir, iFile));\r
+ link.setAttribute("href", getShortPathName(imgDir, iFile));\r
Element text = document.createElement("text");\r
text.setTextContent(iFile.getName());\r
link.appendChild(text);\r