Newer
Older
adjustgpx-gui / src / main / java / osm / jp / gpx / ImportPicture.java
@haya4 haya4 on 25 Apr 2020 9 KB ImgFolder
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;
        }
    }
}