package osm.jp.gpx;
import java.io.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.ResourceBundle;
import java.util.TimeZone;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import javax.xml.parsers.*;
import javax.xml.transform.TransformerException;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.ImageWriteException;
import org.xml.sax.SAXException;
public class ImportPicture extends Thread {
/**
* 実行中に発生したExceptionを保持する場所
*/
public Exception ex = null;
/**
* ログ設定プロパティファイルのファイル内容
*/
protected static final String LOGGING_PROPERTIES_DATA
= "handlers=java.util.logging.ConsoleHandler\n"
+ ".level=FINEST\n"
+ "java.util.logging.ConsoleHandler.level=INFO\n"
+ "java.util.logging.ConsoleHandler.formatter=osm.jp.gpx.YuuLogFormatter";
/**
* static initializer によるログ設定の初期化
*/
public static final Logger LOGGER = Logger.getLogger("CommandLogging");
static {
try (InputStream inStream = new ByteArrayInputStream(LOGGING_PROPERTIES_DATA.getBytes("UTF-8"))) {
try {
LogManager.getLogManager().readConfiguration(inStream);
// "ログ設定: LogManagerを設定しました。"
LOGGER.config("LoggerSettings: LogManager setuped.");
}
catch (IOException e) {
// LogManager設定の際に例外が発生しました.
String str = "LoggerSettings: Exception occered:" + e.toString();
LOGGER.warning(str);
}
}
catch (UnsupportedEncodingException e) {
String str = "LoggerSettings: Not supported 'UTF-8' encoding: " + e.toString();
LOGGER.severe(str);
} catch (IOException e1) {
LOGGER.severe(e1.toString());
}
}
/** メイン
* 画像ファイルをGPXファイルに取り込みます。
*
* ・画像ファイルの更新日付をその画像の撮影日時とします。(Exi情報は無視します)
* ※ 対象とするファイルは'*.jpg'のみ
* ・精確な時刻との時差を入力することで、撮影日時を補正します。
* ・画像ファイルの更新日付リストをCSV形式のファイルとして出力する。
* ・・結果は、取り込み元のGPXファイルとは別に、元ファイル名にアンダーバー「_」を付加した.ファイルに出力します。
*
* exp) $ java -cp .:AdjustTime.jar:commons-imaging-1.0-SNAPSHOT.jar [AdjustTime.ini]
* exp) > java -cp .;AdjustTime.jar;commons-imaging-1.0-SNAPSHOT.jar [AdjustTime.ini]
*
* @param argv
* argv[0] = INIファイルのパス名
*
* @throws IOException
* @throws ImageReadException
*/
public static void main(String[] argv) throws Exception
{
ImportPicture obj = new ImportPicture();
obj.setUp(((argv.length < 1) ? AppParameters.FILE_PATH : argv[0]));
}
public File gpxDir;
public ImgFolder imgFolder;
//public File outDir;
public ArrayList<File> gpxFiles = new ArrayList<>();
public AppParameters params;
private static final String EXIF_DATE_TIME_FORMAT_STRING = "yyyy:MM:dd HH:mm:ss";
public static final ResourceBundle i18n = ResourceBundle.getBundle("i18n");
public void setUp(String paramFilePath) throws Exception {
System.out.println("Param File = '"+ paramFilePath +"'");
this.params = new AppParameters(paramFilePath);
params.printout();
this.ex = null;
// AppParameters.IMG_SOURCE_FOLDER に置き換え
imgFolder = new ImgFolder(params);
this.gpxDir = params.getGpxSourceFolder();
if (this.gpxDir != null) {
if (!this.gpxDir.exists()) {
// GPXファイルまたはディレクトリが存在しません。('%s')
System.out.println(
String.format(i18n.getString("msg.100"), gpxDir.getAbsolutePath())
);
return;
}
}
else {
this.gpxDir = imgFolder.getImgDir();
}
// 指定されたディレクトリ内のGPXファイルすべてを対象とする
if (this.gpxDir.isDirectory()) {
File[] files = this.gpxDir.listFiles();
if (files == null) {
// 対象となるGPXファイルがありませんでした。('%s')
System.out.println(
String.format(i18n.getString("msg.110"), this.gpxDir.getAbsolutePath())
);
return;
}
if (params.isImgOutputAll() && (files.length > 1)) {
// "複数のGPXファイルがあるときには、'IMG.OUTPUT_ALL'オプションは指定できません。"
System.out.println(
i18n.getString("msg.120")
);
return;
}
java.util.Arrays.sort(
files, new java.util.Comparator<File>() {
@Override
public int compare(File file1, File file2){
return file1.getName().compareTo(file2.getName());
}
}
);
for (File file : files) {
if (file.isFile()) {
String filename = file.getName().toUpperCase();
if (filename.toUpperCase().endsWith(".GPX")) {
if (!filename.toUpperCase().endsWith("_.GPX") || params.isGpxReuse()) {
this.gpxFiles.add(file);
}
}
}
}
}
else {
this.gpxFiles.add(this.gpxDir);
}
// 出力ファイル
// AppParameters.IMG_OUTPUT に置き換え
File outDir = new File(params.getProperty(AppParameters.IMG_OUTPUT_FOLDER));
if (params.isImgOutput()) {
outDir = new File(outDir, imgFolder.getImgDir().getName());
}
else {
outDir = gpxDir;
}
imgFolder.setOutDir(outDir);
this.start();
try {
this.join();
} catch(InterruptedException end) {}
if (this.ex != null) {
throw this.ex;
}
}
/**
* @code{
<wpt lat="35.25714922" lon="139.15490497">
<ele>62.099998474121094</ele>
<time>2012-06-11T00:44:38Z</time>
<hdop>0.75</hdop>
<name><![CDATA[写真]]></name>
<cmt><![CDATA[精度: 3.0m]]></cmt>
<link href="2012-06-11_09-44-38.jpg">
<text>2012-06-11_09-44-38.jpg</text>
</link>
<sat>9</sat>
</wpt>
* }
*/
@Override
public void run() {
try {
for (File gpxFile : this.gpxFiles) {
imgFolder.procGPXfile(new GpxFile(params, gpxFile));
}
}
catch(ParserConfigurationException | SAXException | IOException | ParseException | ImageReadException | ImageWriteException | IllegalArgumentException | TransformerException e) {
e.printStackTrace();
this.ex = new Exception(e);
}
}
public static final String TIME_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ss'Z'";
public static Date toUTCDate(String timeStr) throws ParseException {
DateFormat dfUTC = new SimpleDateFormat(TIME_FORMAT_STRING);
dfUTC.setTimeZone(TimeZone.getTimeZone("UTC"));
return dfUTC.parse(timeStr);
}
public static String toUTCString(Date localdate) {
DateFormat dfUTC = new SimpleDateFormat(TIME_FORMAT_STRING);
dfUTC.setTimeZone(TimeZone.getTimeZone("UTC"));
return dfUTC.format(localdate);
}
/**
* DateをEXIFの文字列に変換する。
* 注意:EXiFの撮影時刻はUTC時間ではない
* @param localdate
* @return
*/
public static String toEXIFString(Date localdate) {
DateFormat dfUTC = new SimpleDateFormat(EXIF_DATE_TIME_FORMAT_STRING);
return dfUTC.format(localdate);
}
/**
* EXIFの文字列をDateに変換する。
* 注意:EXiFの撮影時刻はUTC時間ではない
* @param timeStr
* @return
* @throws ParseException
*/
public static Date toEXIFDate(String timeStr) throws ParseException {
DateFormat dfUTC = new SimpleDateFormat(EXIF_DATE_TIME_FORMAT_STRING);
//dfUTC.setTimeZone(TimeZone.getTimeZone("UTC"));
return dfUTC.parse(timeStr);
}
static String getShortPathName(File dir, File iFile) {
String dirPath = dir.getAbsolutePath();
String filePath = iFile.getAbsolutePath();
if (filePath.startsWith(dirPath)) {
return filePath.substring(dirPath.length()+1);
}
else {
return filePath;
}
}
}