3 import java.text.DecimalFormat;
\r
4 import java.text.ParseException;
\r
5 import java.text.SimpleDateFormat;
\r
6 import java.util.ArrayList;
\r
7 import java.util.Arrays;
\r
8 import java.util.Calendar;
\r
9 import java.util.Comparator;
\r
10 import java.util.Date;
\r
11 import java.util.GregorianCalendar;
\r
12 import java.util.HashMap;
\r
13 import java.util.Iterator;
\r
14 import java.util.Set;
\r
15 import java.util.TimeZone;
\r
16 import java.util.logging.LogManager;
\r
17 import java.util.logging.Logger;
\r
19 import javax.xml.parsers.*;
\r
20 import javax.xml.transform.OutputKeys;
\r
21 import javax.xml.transform.Transformer;
\r
22 import javax.xml.transform.TransformerFactory;
\r
23 import javax.xml.transform.dom.DOMSource;
\r
24 import javax.xml.transform.stream.StreamResult;
\r
26 import org.apache.commons.imaging.ImageReadException;
\r
27 import org.apache.commons.imaging.ImageWriteException;
\r
28 import org.apache.commons.imaging.Imaging;
\r
29 import org.apache.commons.imaging.common.ImageMetadata;
\r
30 import org.apache.commons.imaging.common.RationalNumber;
\r
31 import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
\r
32 import org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter;
\r
33 import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
\r
34 import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants;
\r
35 import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants;
\r
36 import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;
\r
37 import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;
\r
38 import org.w3c.dom.*;
\r
40 public class ImportPicture {
\r
41 public static File gpxDir = new File(".");
\r
42 public static File outDir = null;
\r
45 * ログ設定プロパティファイルのファイル内容
\r
47 protected static final String LOGGING_PROPERTIES_DATA
\r
48 = "handlers=java.util.logging.ConsoleHandler\n"
\r
50 + "java.util.logging.ConsoleHandler.level=INFO\n"
\r
51 + "java.util.logging.ConsoleHandler.formatter=osm.jp.gpx.YuuLogFormatter";
\r
54 * static initializer によるログ設定の初期化
\r
56 public static final Logger logger = Logger.getLogger("CommandLogging");
\r
58 InputStream inStream = null;
\r
60 inStream = new ByteArrayInputStream(LOGGING_PROPERTIES_DATA.getBytes("UTF-8"));
\r
62 LogManager.getLogManager().readConfiguration(inStream);
\r
63 logger.config("ログ設定: LogManagerを設定しました。");
\r
65 catch (IOException e) {
\r
66 logger.warning("ログ設定: LogManager設定の際に例外が発生しました。:" + e.toString());
\r
69 catch (UnsupportedEncodingException e) {
\r
70 logger.severe("ログ設定: UTF-8エンコーディングがサポートされていません。:" + e.toString());
\r
74 if (inStream != null) {
\r
77 } catch (IOException e) {
\r
78 logger.warning("ログ設定: ログ設定プロパティファイルのストリームクローズ時に例外が発生しました。:"+ e.toString());
\r
84 * 画像ファイルをGPXファイルに取り込みます。
\r
86 * ・画像ファイルの更新日付をその画像の撮影日時とします。(Exi情報は無視します)
\r
87 * ※ 対象とするファイルは'*.jpg'のみ
\r
88 * ・精確な時刻との時差を入力することで、撮影日時を補正します。
\r
89 * ・画像ファイルの更新日付リストをCSV形式のファイルとして出力する。
\r
90 * ・・結果は、取り込み元のGPXファイルとは別に、元ファイル名にアンダーバー「_」を付加した.ファイルに出力します。
\r
94 * argv[0] = 画像ファイルが格納されているディレクトリ
\r
95 * argv[1] = 時刻補正の基準とする画像ファイル
\r
96 * argv[2] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd'T'HH:mm:ss"
\r
97 * argv[3] = [EXIF] EXIF情報の書き換えを行う / [not] EXIF情報の書き換えを行わない
\r
98 * argv[4] = 撮影位置をロギングしたGPXファイル
\r
100 * @throws IOException
\r
101 * @throws ImageReadException
\r
103 public static void main(String[] argv) throws Exception
\r
107 if (argv.length > 0) {
\r
108 gpxDir = new File(argv[0]);
\r
111 if (argv.length < 4) {
\r
112 System.out.println("!!! Illigal command call. !!!");
\r
113 System.out.println("> java -cp .:AdjustTime.jar:commons-imaging-1.0-SNAPSHOT.jar <targetDir> <time base image> <time> {EXIF/not} (gpx)");
\r
114 System.out.println("> java -cp .:AdjustTime.jar:commons-imaging-1.0-SNAPSHOT.jar. IMG_01234.JPG 2012-06-15T12:52:22 EXIF");
\r
115 System.out.println("> java -cp .:AdjustTime.jar . IMG_01234.JPG 2012-06-15T12:52:22 not");
\r
116 System.out.println();
\r
120 // 基準時刻ファイルの「更新日時」を使って時刻合わせを行う。
\r
121 File baseFile = new File(gpxDir, argv[1]);
\r
122 jptime = new Date(baseFile.lastModified());
\r
125 boolean exif = false;
\r
126 if (argv[3].toUpperCase().equals("EXIF")) {
\r
130 // 第6引数が指定されなければ、指定されたディレクトリ内のGPXファイルすべてを対象とする
\r
131 ArrayList<File> gpxFiles = new ArrayList<>();
\r
132 if (argv.length > 4) {
\r
133 gpxFiles.add(new File(gpxDir, argv[4]));
\r
136 File[] files = gpxDir.listFiles();
\r
137 for (File file : files) {
\r
138 if (file.isFile()) {
\r
139 String filename = file.getName().toUpperCase();
\r
140 if (filename.endsWith(".GPX")) {
\r
141 if (!filename.endsWith("_.GPX")) {
\r
142 gpxFiles.add(file);
\r
152 <wpt lat="35.25714922" lon="139.15490497">
\r
153 <ele>62.099998474121094</ele>
\r
154 <time>2012-06-11T00:44:38Z</time>
\r
156 <name><![CDATA[写真]]></name>
\r
157 <cmt><![CDATA[精度: 3.0m]]></cmt>
\r
158 <link href="2012-06-11_09-44-38.jpg">
\r
159 <text>2012-06-11_09-44-38.jpg</text>
\r
164 DocumentBuilderFactory factory;
\r
165 DocumentBuilder builder;
\r
168 for (File gpxFile : gpxFiles) {
\r
169 String fileName = gpxFile.getName();
\r
170 String iStr = fileName.substring(0, fileName.length() - 4);
\r
172 File outputFile = new File(gpxFile.getParent(), iStr +"_.gpx");
\r
173 System.out.println(iStr + " => "+ outputFile.getName());
\r
175 factory = DocumentBuilderFactory.newInstance();
\r
176 builder = factory.newDocumentBuilder();
\r
177 factory.setIgnoringElementContentWhitespace(true);
\r
178 factory.setIgnoringComments(true);
\r
179 factory.setValidating(true);
\r
181 // GPX file --> Node root
\r
182 DOMImplementation domImpl = builder.getDOMImplementation();
\r
183 document = domImpl.createDocument("", "gpx", null);
\r
188 <name><![CDATA[Tracked with OSMTracker for Android?]]></name>
\r
189 <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
191 <trkpt lat="35.32123832" lon="139.56965631">
\r
192 <ele>47.20000076293945</ele>
\r
193 <time>2012-06-15T03:00:29Z</time>
\r
198 <wpt lat="35.2564461" lon="139.15437809">
\r
202 HashMap<Long,Element> map = new HashMap<>();
\r
203 Element trk = null;
\r
204 gpx = builder.parse(gpxFile).getFirstChild();
\r
205 NodeList nodes = gpx.getChildNodes();
\r
206 for (int i=0; i < nodes.getLength(); i++) {
\r
207 Node node2 = nodes.item(i);
\r
208 if (node2.getNodeName().equals("trk")) {
\r
209 trk = (Element) node2;
\r
210 trkptMap(trk, map);
\r
215 dfjp.setTimeZone(TimeZone.getTimeZone("JST"));
\r
216 String timeStr = argv[2];
\r
218 Date t = dfjp.parse(timeStr);
\r
219 long delta = t.getTime() - jptime.getTime();
\r
222 * GPXへ割りつける開始時刻と終了時刻を求める
\r
224 long gpxStartTime = (new Date()).getTime(); // 対象とする開始時刻(現在時刻)
\r
225 long gpxEndTime = 0L; // 対象とする終了時刻
\r
226 Set<Long> keySet = map.keySet(); //すべてのキー値を取得
\r
227 for (Long timeLong : keySet) {
\r
228 long gpxTime = timeLong;
\r
229 if (gpxStartTime > gpxTime) {
\r
230 gpxStartTime = gpxTime;
\r
232 if (gpxEndTime < gpxTime) {
\r
233 gpxEndTime = gpxTime;
\r
237 System.out.println(" 時差: "+ (delta / 1000) +"(sec)");
\r
238 System.out.println(" Target GPX: ["+ gpxFile.getName() +"]");
\r
239 System.out.println("GPX start time: "+ dfjp.format(new Date(gpxStartTime)) + "\t[GMT " + dfuk.format(new Date(gpxStartTime))+"]");
\r
240 System.out.println(" GPX end time: "+ dfjp.format(new Date(gpxEndTime)) + "\t[GMT " + dfuk.format(new Date(gpxEndTime))+"]");
\r
241 System.out.println();
\r
242 System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");
\r
243 System.out.println(" name | UpdateTime | GPStime | Latitude | Longitude | ele |magvar|");
\r
244 System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");
\r
245 proc(gpxDir, delta, gpxStartTime, gpxEndTime, map, exif, gpx);
\r
246 System.out.println("------------|--------------------|--------------------|------------|------------|--------|------|");
\r
248 catch (ParseException e) {
\r
249 System.out.println("'"+ timeStr +"' の書式が違います("+ TIME_FORMAT_STRING +")");
\r
254 DOMSource source = new DOMSource(gpx);
\r
255 FileOutputStream os = new FileOutputStream(outputFile);
\r
256 StreamResult result = new StreamResult(os);
\r
257 TransformerFactory transFactory = TransformerFactory.newInstance();
\r
258 Transformer transformer = transFactory.newTransformer();
\r
259 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
\r
260 transformer.setOutputProperty(OutputKeys.METHOD, "xml");
\r
261 transformer.transform(source, result);
\r
267 * @throws ParseException
\r
268 * @throws IOException
\r
269 * @throws ImageReadException
\r
270 * @throws ImageWriteException
\r
272 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
273 DecimalFormat yearFormatter = new DecimalFormat("0000");
\r
274 DecimalFormat monthFormatter = new DecimalFormat("00");
\r
275 DecimalFormat dayFormatter = new DecimalFormat("00");
\r
277 File[] files = dir.listFiles();
\r
278 Arrays.sort(files, new FileSort());
\r
279 for (File image : files) {
\r
280 if (image.isDirectory()) {
\r
281 proc(image, delta, gpxStartTime, gpxEndTime, map, exifWrite, gpx);
\r
284 String imageName = image.getName();
\r
285 if (checkFile(imageName)) {
\r
286 Date itime = new Date(image.lastModified());
\r
287 Date uktime = new Date(itime.getTime() + delta);
\r
288 if ((uktime.getTime() >= gpxStartTime) && (uktime.getTime() <= gpxEndTime)) {
\r
289 Element trkpt = trkpt(map, uktime);
\r
290 if (trkpt != null) {
\r
291 System.out.print(String.format("%12s|", image.getName()));
\r
292 System.out.print(String.format("%20s ", dfjp.format(itime)));
\r
293 System.out.print(String.format("%20s|", dfjp.format(uktime)));
\r
295 Element wpt = createWptTag(image, uktime.getTime(), trkpt);
\r
296 String latStr = wpt.getAttribute("lat");
\r
297 String lonStr = wpt.getAttribute("lon");
\r
298 System.out.print(String.format("%12s %12s|", latStr, lonStr));
\r
299 double latitude = Double.parseDouble(latStr);
\r
300 double longitude = Double.parseDouble(lonStr);
\r
302 String eleStr = null;
\r
303 String magvarStr = null;
\r
304 NodeList nodes = wpt.getChildNodes(); // 子ノードを取得
\r
305 for (int i4=0; i4< nodes.getLength(); i4++) {
\r
306 Node node = nodes.item(i4);
\r
307 if (node != null) {
\r
308 if (node.getNodeName().equals("ele")) {
\r
309 eleStr = node.getFirstChild().getNodeValue();
\r
310 System.out.println(String.format("%8s|", eleStr));
\r
313 if (node.getNodeName().equals("magvar")) {
\r
314 magvarStr = node.getFirstChild().getNodeValue();
\r
315 System.out.println(String.format("%6s|", magvarStr));
\r
320 System.out.println("-");
\r
326 TiffOutputSet outputSet = null;
\r
327 FileOutputStream fos = null;
\r
329 ImageMetadata meta = Imaging.getMetadata(image);
\r
330 JpegImageMetadata jpegMetadata = (JpegImageMetadata)meta;
\r
331 if (jpegMetadata != null) {
\r
332 TiffImageMetadata exif = jpegMetadata.getExif();
\r
333 if (exif != null) {
\r
334 outputSet = exif.getOutputSet();
\r
338 if (outputSet == null) {
\r
339 System.out.println("added : new tiff output set");
\r
340 outputSet = new TiffOutputSet();
\r
343 //---- EXIF_TAG_DATE_TIME_ORIGINAL / 「撮影日時/オリジナル画像の生成日時」----
\r
344 TiffOutputDirectory exifDir = outputSet.getOrCreateExifDirectory();
\r
346 Calendar cal = GregorianCalendar.getInstance();
\r
347 cal.setTime(uktime);
\r
348 exifDir.removeField(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
\r
349 exifDir.add(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL, new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").format(cal.getTime()));
\r
352 //---- EXIF GPS_TIME_STAMP ----
\r
353 TiffOutputDirectory gpsDir = outputSet.getOrCreateGPSDirectory();
\r
355 Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));
\r
356 cal.setTime(uktime);
\r
357 final String yearStr = yearFormatter.format(cal.get(Calendar.YEAR));
\r
358 final String monthStr = monthFormatter.format(cal.get(Calendar.MONTH) + 1);
\r
359 final String dayStr = dayFormatter.format(cal.get(Calendar.DAY_OF_MONTH));
\r
360 final String dateStamp = yearStr +":"+ monthStr +":"+ dayStr;
\r
362 gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP);
\r
363 gpsDir.add(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP,
\r
364 RationalNumber.valueOf(cal.get(Calendar.HOUR_OF_DAY)),
\r
365 RationalNumber.valueOf(cal.get(Calendar.MINUTE)),
\r
366 RationalNumber.valueOf(cal.get(Calendar.SECOND)));
\r
367 gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_DATE_STAMP);
\r
368 gpsDir.add(GpsTagConstants.GPS_TAG_GPS_DATE_STAMP, dateStamp);
\r
371 //---- EXIF GPS elevation/ALTITUDE ----
\r
372 if (eleStr != null) {
\r
373 final double altitude = Double.parseDouble(eleStr);
\r
374 gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_ALTITUDE);
\r
375 gpsDir.add(GpsTagConstants.GPS_TAG_GPS_ALTITUDE, RationalNumber.valueOf(altitude));
\r
378 //---- EXIF GPS_ ----
\r
379 final String longitudeRef = (longitude < 0 ? "W" : "E");
\r
380 longitude = Math.abs(longitude);
\r
381 final String latitudeRef = (latitude < 0 ? "S" : "N");
\r
382 latitude = Math.abs(latitude);
\r
384 gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);
\r
385 gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF, longitudeRef);
\r
386 gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);
\r
387 gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF, latitudeRef);
\r
389 double value = longitude;
\r
390 final double longitudeDegrees = (long) value;
\r
393 final double longitudeMinutes = (long) value;
\r
396 final double longitudeSeconds = value;
\r
397 gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LONGITUDE);
\r
398 gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LONGITUDE,
\r
399 RationalNumber.valueOf(longitudeDegrees),
\r
400 RationalNumber.valueOf(longitudeMinutes),
\r
401 RationalNumber.valueOf(longitudeSeconds));
\r
404 double value = latitude;
\r
405 final double latitudeDegrees = (long) value;
\r
408 final double latitudeMinutes = (long) value;
\r
411 final double latitudeSeconds = value;
\r
412 gpsDir.removeField(GpsTagConstants.GPS_TAG_GPS_LATITUDE);
\r
413 gpsDir.add(GpsTagConstants.GPS_TAG_GPS_LATITUDE,
\r
414 RationalNumber.valueOf(latitudeDegrees),
\r
415 RationalNumber.valueOf(latitudeMinutes),
\r
416 RationalNumber.valueOf(latitudeSeconds));
\r
419 ExifRewriter rewriter = new ExifRewriter();
\r
421 if (outDir == null) {
\r
422 outDir = new File(dir, "converted");
\r
425 fos = new FileOutputStream(new File(outDir, imageName));
\r
426 rewriter.updateExifMetadataLossy(image, fos, outputSet);
\r
435 Element temp = getCopy(gpx.getOwnerDocument(), wpt);
\r
436 gpx.appendChild(temp);
\r
444 static Document document;
\r
447 * 2012-06-10T05:09:46Z (日本時間の'2012-06-10T14:09:46')
\r
449 public static final String TIME_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ss";
\r
450 public static SimpleDateFormat dfjp = new SimpleDateFormat(TIME_FORMAT_STRING);
\r
451 public static SimpleDateFormat dfuk = new SimpleDateFormat(TIME_FORMAT_STRING +"'Z'");
\r
454 * XMLエレメント<trkpt>をTIMEでキー付したHashMapを生成する<br>
\r
456 * <trk><trkseg><trkpt><time>2014-01-01T00:59:09Z</time></trkpt></trkseg></trk>
\r
460 * @throws ParseException
\r
462 public static void trkptMap(Element trk, HashMap<Long,Element> map) throws ParseException {
\r
463 dfuk.setTimeZone(TimeZone.getTimeZone("GMT"));
\r
465 NodeList nodes1 = trk.getChildNodes();
\r
466 for (int i1=0; i1 < nodes1.getLength(); i1++) {
\r
467 Node node2 = nodes1.item(i1);
\r
468 if (node2.getNodeName().equals("trkseg")) {
\r
469 Element trkseg = (Element) node2;
\r
470 NodeList nodes2 = trkseg.getChildNodes();
\r
471 for (int i2=0; i2 < nodes2.getLength(); i2++) {
\r
472 Node node3 = nodes2.item(i2);
\r
473 if (node3.getNodeName().equals("trkpt")) {
\r
474 Element trkpt = (Element) node3;
\r
476 NodeList nodes3 = trkpt.getChildNodes();
\r
477 for (int i3=0; i3 < nodes3.getLength(); i3++) {
\r
478 Node node4 = nodes3.item(i3);
\r
479 if (node4.getNodeName().equals("time")) {
\r
480 Element time = (Element) node4;
\r
481 NodeList nodes4 = time.getChildNodes(); // 子ノードを取得
\r
482 for (int i4=0; i4< nodes4.getLength(); i4++) {
\r
483 Node node5 = nodes4.item(i4);
\r
484 if (node5 != null) {
\r
485 if (node5.getNodeType() == Node.TEXT_NODE) {
\r
486 String timeStr = node5.getNodeValue();
\r
487 long t = dfuk.parse(timeStr).getTime();
\r
488 map.put(t, getCopy(trk.getOwnerDocument(), trkpt));
\r
501 * < lat="35.32123832" lon="139.56965631">
\r
502 * <ele>47.20000076293945</ele>
\r
503 * <time>2012-06-15T03:00:29Z</time>
\r
508 * @throws ParseException
\r
510 public static Element trkpt(HashMap<Long,Element> map, Date jptime) throws ParseException {
\r
511 Double R = 20000000 / Math.PI; // 地球の半径(m)
\r
512 long sa = 2L * 3600000L;
\r
513 long jpt = jptime.getTime();
\r
514 Element ret = null;
\r
515 Element mae = null;
\r
517 Set<Long> keySet = map.keySet(); //すべてのキー値を取得
\r
518 Iterator<Long> keyIte = keySet.iterator();
\r
519 while (keyIte.hasNext()) { //ループ。反復子iteratorによる キー 取得
\r
520 Long time = keyIte.next();
\r
522 if (Math.abs(jpt - t) < sa) {
\r
523 sa = Math.abs(jpt - t);
\r
524 ret = map.get(time);
\r
527 // 直前の位置と、現在地から進行方向を求める
\r
528 NodeList nodes3 = ret.getChildNodes();
\r
529 Element magvar = null;
\r
530 for (int i3=0; i3 < nodes3.getLength(); i3++) {
\r
531 Node node4 = nodes3.item(i3);
\r
532 if (node4.getNodeName().toLowerCase().equals("magvar")) {
\r
533 magvar = (Element) node4;
\r
537 if (magvar == null) {
\r
539 Double maeLAT = null;
\r
540 Double maeLON = null;
\r
541 Double imaLAT = null;
\r
542 Double imaLON =null;
\r
544 // 経度(longitude)と経度から進行方向を求める
\r
545 NamedNodeMap nodeMap = mae.getAttributes();
\r
546 if (null != nodeMap) {
\r
547 for (int j=0; j < nodeMap.getLength(); j++ ) {
\r
548 switch (nodeMap.item(j).getNodeName()) {
\r
550 String latStr = nodeMap.item(j).getNodeValue();
\r
551 maeLAT = new Double(latStr);
\r
554 String lonStr = nodeMap.item(j).getNodeValue();
\r
555 maeLON = new Double(lonStr);
\r
559 nodeMap = ret.getAttributes();
\r
560 for (int j=0; j < nodeMap.getLength(); j++ ) {
\r
561 switch (nodeMap.item(j).getNodeName()) {
\r
563 String latStr = nodeMap.item(j).getNodeValue();
\r
564 imaLAT = new Double(latStr);
\r
567 String lonStr = nodeMap.item(j).getNodeValue();
\r
568 imaLON = new Double(lonStr);
\r
572 Double dLON = imaLON - maeLON;
\r
573 Double dLAT = imaLAT - maeLAT;
\r
574 Double r = Math.cos(Math.toRadians((imaLAT + maeLAT) * 2)) * R;
\r
575 Double x = Math.toRadians(imaLON - maeLON) * r;
\r
576 Double y = Math.toRadians(imaLAT - maeLAT) * R;
\r
577 double rad = Math.toDegrees(Math.atan(y / x));
\r
578 System.out.println("magvar = " + rad);
\r
579 magvar = ret.getOwnerDocument().createElement("magvar");
\r
580 magvar.setTextContent(Double.toString(rad));
\r
581 ret.appendChild(magvar);
\r
586 mae = map.get(time);
\r
589 if (sa < (60000L * 10L)) {
\r
590 // System.out.println(dfuk.format(jpt) +" ("+ sa +")");
\r
597 * 対象は '*.JPG' のみ対象とする
\r
601 public static boolean checkFile(String name) {
\r
602 return ((name != null) && name.toUpperCase().endsWith(".JPG"));
\r
606 * <wpt lat="35.25714922" lon="139.15490497">
\r
607 * <ele>62.099998474121094</ele>
\r
608 * <time>2012-06-11T00:44:38Z</time>
\r
609 * <name><![CDATA[写真]]></name>
\r
610 * <link href="2012-06-11_09-44-38.jpg">
\r
611 * <text>2012-06-11_09-44-38.jpg</text>
\r
615 * <trkpt lat="35.32123832" lon="139.56965631">
\r
616 * <ele>47.20000076293945</ele>
\r
617 * <time>2012-06-15T03:00:29Z</time>
\r
625 public static Element createWptTag(File iFile, long timestamp, Element trkpt) {
\r
626 Element wpt = document.createElement("wpt");
\r
628 NamedNodeMap nodeMap = trkpt.getAttributes();
\r
629 if (null != nodeMap) {
\r
630 for (int j=0; j < nodeMap.getLength(); j++ ) {
\r
631 switch (nodeMap.item(j).getNodeName()) {
\r
633 String lat = nodeMap.item(j).getNodeValue();
\r
634 wpt.setAttribute("lat", lat);
\r
637 String lon = nodeMap.item(j).getNodeValue();
\r
638 wpt.setAttribute("lon", lon);
\r
644 NodeList nodes1 = trkpt.getChildNodes();
\r
645 for (int i1=0; i1 < nodes1.getLength(); i1++) {
\r
646 Node node1 = nodes1.item(i1);
\r
647 NodeList nodes2 = node1.getChildNodes();
\r
648 switch (node1.getNodeName()) {
\r
650 for (int i2=0; i2 < nodes2.getLength(); i2++) {
\r
651 Node node2 = nodes2.item(i2);
\r
652 if (node2 != null) {
\r
653 if (node2.getNodeType() == Node.TEXT_NODE) {
\r
654 String eleStr = node2.getNodeValue();
\r
655 Element eleE = document.createElement("ele");
\r
656 eleE.setTextContent(eleStr);
\r
657 wpt.appendChild(eleE);
\r
663 for (int i2=0; i2 < nodes2.getLength(); i2++) {
\r
664 Node node2 = nodes2.item(i2);
\r
665 if (node2 != null) {
\r
666 if (node2.getNodeType() == Node.TEXT_NODE) {
\r
667 String timeStr = node2.getNodeValue();
\r
668 Element timeE = document.createElement("time");
\r
669 timeE.setTextContent(timeStr);
\r
670 wpt.appendChild(timeE);
\r
676 for (int i2=0; i2 < nodes2.getLength(); i2++) {
\r
677 Node node2 = nodes2.item(i2);
\r
678 if (node2 != null) {
\r
679 if (node2.getNodeType() == Node.TEXT_NODE) {
\r
680 String magvarStr = node2.getNodeValue();
\r
681 Element magvarE = document.createElement("magvar");
\r
682 magvarE.setTextContent(magvarStr);
\r
683 wpt.appendChild(magvarE);
\r
691 Element name = document.createElement("name");
\r
692 name.appendChild(document.createCDATASection("写真"));
\r
693 wpt.appendChild(name);
\r
695 Element link = document.createElement("link");
\r
696 link.setAttribute("href", getShortPathName(gpxDir, iFile));
\r
697 Element text = document.createElement("text");
\r
698 text.setTextContent(iFile.getName());
\r
699 link.appendChild(text);
\r
700 wpt.appendChild(link);
\r
705 static String getShortPathName(File dir, File iFile) {
\r
706 String dirPath = dir.getAbsolutePath();
\r
707 String filePath = iFile.getAbsolutePath();
\r
708 if (filePath.startsWith(dirPath)) {
\r
709 return filePath.substring(dirPath.length()+1);
\r
716 public static Element getCopy(Document doc, Node node) {
\r
717 Element root = doc.createElement(node.getNodeName());
\r
719 NamedNodeMap nodeMap = node.getAttributes();
\r
720 if (null != nodeMap) {
\r
721 for (int j=0; j < nodeMap.getLength(); j++ ) {
\r
722 root.setAttribute(nodeMap.item(j).getNodeName(), nodeMap.item(j).getNodeValue());
\r
726 NodeList nodes = node.getChildNodes();
\r
727 for (int i=0; i < nodes.getLength(); i++) {
\r
728 Node node2 = nodes.item(i);
\r
729 if (node2.getNodeType() == Node.ELEMENT_NODE) {
\r
730 root.appendChild(getCopy(doc, node2));
\r
732 else if (node2.getNodeType() == Node.TEXT_NODE) {
\r
733 String str = node2.getNodeValue();
\r
734 Text textContents = doc.createTextNode(str);
\r
735 root.appendChild(textContents);
\r
737 else if (node2.getNodeType() == Node.CDATA_SECTION_NODE) {
\r
738 String str = node2.getNodeValue();
\r
739 CDATASection cdataSection = doc.createCDATASection(str);
\r
740 root.appendChild(cdataSection);
\r
747 * ファイル名の順序に並び替えるためのソートクラス
\r
751 static class FileSort implements Comparator<File>{
\r
753 public int compare(File src, File target){
\r
754 int diff = src.getName().compareTo(target.getName());
\r