001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.io.session;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.io.File;
007import java.io.IOException;
008import java.util.ArrayList;
009import java.util.Date;
010import java.util.List;
011
012import org.openstreetmap.josm.Main;
013import org.openstreetmap.josm.data.coor.LatLon;
014import org.openstreetmap.josm.gui.layer.GpxLayer;
015import org.openstreetmap.josm.gui.layer.Layer;
016import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
017import org.openstreetmap.josm.gui.layer.geoimage.ImageEntry;
018import org.openstreetmap.josm.gui.progress.ProgressMonitor;
019import org.openstreetmap.josm.io.IllegalDataException;
020import org.w3c.dom.Element;
021import org.w3c.dom.Node;
022import org.w3c.dom.NodeList;
023
024public class GeoImageSessionImporter implements SessionLayerImporter {
025
026    @Override
027    public Layer load(Element elem, SessionReader.ImportSupport support, ProgressMonitor progressMonitor)
028            throws IOException, IllegalDataException {
029        String version = elem.getAttribute("version");
030        if (!"0.1".equals(version)) {
031            throw new IllegalDataException(tr("Version ''{0}'' of meta data for geoimage layer is not supported. Expected: 0.1", version));
032        }
033
034        List<ImageEntry> entries = new ArrayList<>();
035        NodeList imgNodes = elem.getChildNodes();
036        boolean useThumbs = false;
037        for (int i = 0; i < imgNodes.getLength(); ++i) {
038            Node imgNode = imgNodes.item(i);
039            if (imgNode.getNodeType() == Node.ELEMENT_NODE) {
040                Element imgElem = (Element) imgNode;
041                if ("geoimage".equals(imgElem.getTagName())) {
042                    ImageEntry entry = new ImageEntry();
043                    NodeList attrNodes = imgElem.getChildNodes();
044                    for (int j = 0; j < attrNodes.getLength(); ++j) {
045                        Node attrNode = attrNodes.item(j);
046                        if (attrNode.getNodeType() == Node.ELEMENT_NODE) {
047                            Element attrElem = (Element) attrNode;
048                            try {
049                                switch(attrElem.getTagName()) {
050                                case "file":
051                                    entry.setFile(new File(attrElem.getTextContent()));
052                                    break;
053                                case "position":
054                                    double lat = Double.parseDouble(attrElem.getAttribute("lat"));
055                                    double lon = Double.parseDouble(attrElem.getAttribute("lon"));
056                                    entry.setPos(new LatLon(lat, lon));
057                                    break;
058                                case "speed":
059                                    entry.setSpeed(Double.valueOf(attrElem.getTextContent()));
060                                    break;
061                                case "elevation":
062                                    entry.setElevation(Double.valueOf(attrElem.getTextContent()));
063                                    break;
064                                case "gps-time":
065                                    entry.setGpsTime(new Date(Long.parseLong(attrElem.getTextContent())));
066                                    break;
067                                case "exif-orientation":
068                                    entry.setExifOrientation(Integer.valueOf(attrElem.getTextContent()));
069                                    break;
070                                case "exif-time":
071                                    entry.setExifTime(new Date(Long.parseLong(attrElem.getTextContent())));
072                                    break;
073                                case "exif-gps-time":
074                                    entry.setExifGpsTime(new Date(Long.parseLong(attrElem.getTextContent())));
075                                    break;
076                                case "exif-coordinates":
077                                    entry.setExifCoor(new LatLon(
078                                            Double.parseDouble(attrElem.getAttribute("lat")),
079                                            Double.parseDouble(attrElem.getAttribute("lon"))));
080                                    break;
081                                case "exif-image-direction":
082                                    entry.setExifImgDir(Double.parseDouble(attrElem.getTextContent()));
083                                    break;
084                                case "is-new-gps-data":
085                                    if (Boolean.parseBoolean(attrElem.getTextContent())) {
086                                        entry.flagNewGpsData();
087                                    }
088                                }
089                                // TODO: handle thumbnail loading
090                            } catch (NumberFormatException e) {
091                                // do nothing
092                                if (Main.isTraceEnabled()) {
093                                    Main.trace(e.getMessage());
094                                }
095                            }
096                        }
097                    }
098                    entries.add(entry);
099                } else if ("show-thumbnails".equals(imgElem.getTagName())) {
100                    useThumbs = Boolean.parseBoolean(imgElem.getTextContent());
101                }
102            }
103        }
104
105        GpxLayer gpxLayer = null;
106        List<SessionReader.LayerDependency> deps = support.getLayerDependencies();
107        if (!deps.isEmpty()) {
108            Layer layer = deps.get(0).getLayer();
109            if (layer instanceof GpxLayer) {
110                gpxLayer = (GpxLayer) layer;
111            }
112        }
113
114        return new GeoImageLayer(entries, gpxLayer, useThumbs);
115    }
116
117}