001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.io.session;
003
004import java.awt.Component;
005import java.awt.GridBagLayout;
006import java.io.IOException;
007import java.util.HashMap;
008import java.util.LinkedHashMap;
009import java.util.Map;
010
011import javax.swing.JLabel;
012import javax.swing.JPanel;
013import javax.swing.SwingConstants;
014
015import org.openstreetmap.josm.data.StructUtils;
016import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryPreferenceEntry;
017import org.openstreetmap.josm.data.imagery.OffsetBookmark;
018import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer;
019import org.openstreetmap.josm.gui.layer.ImageryLayer;
020import org.openstreetmap.josm.gui.layer.TMSLayer;
021import org.openstreetmap.josm.gui.layer.WMSLayer;
022import org.openstreetmap.josm.gui.layer.WMTSLayer;
023import org.openstreetmap.josm.gui.layer.imagery.ImageryFilterSettings;
024import org.openstreetmap.josm.io.session.SessionWriter.ExportSupport;
025import org.openstreetmap.josm.tools.GBC;
026import org.openstreetmap.josm.tools.Utils;
027import org.w3c.dom.Element;
028
029/**
030 * Session exporter for {@link TMSLayer}, {@link WMSLayer} and {@link WMTSLayer}.
031 * @since 5391
032 */
033public class ImagerySessionExporter extends AbstractSessionExporter<ImageryLayer> {
034
035    /**
036     * Constructs a new {@code ImagerySessionExporter}.
037     * @param layer imagery layer to export
038     */
039    public ImagerySessionExporter(ImageryLayer layer) { // NO_UCD (unused code)
040        super(layer);
041    }
042
043    /**
044     * Constructs a new {@code ImagerySessionExporter}.
045     * @param layer TMS layer to export
046     */
047    public ImagerySessionExporter(TMSLayer layer) { // NO_UCD (unused code)
048        super(layer);
049    }
050
051    /**
052     * Constructs a new {@code ImagerySessionExporter}.
053     * @param layer WMS layer to export
054     */
055    public ImagerySessionExporter(WMSLayer layer) { // NO_UCD (unused code)
056        super(layer);
057    }
058
059    /**
060     * Constructs a new {@code ImagerySessionExporter}.
061     * @param layer WMTS layer to export
062     */
063    public ImagerySessionExporter(WMTSLayer layer) { // NO_UCD (unused code)
064        super(layer);
065    }
066
067    @Override
068    public Component getExportPanel() {
069        final JPanel p = new JPanel(new GridBagLayout());
070        export.setSelected(true);
071        final JLabel lbl = new JLabel(layer.getName(), layer.getIcon(), SwingConstants.LEFT);
072        lbl.setToolTipText(layer.getToolTipText());
073        lbl.setLabelFor(export);
074        p.add(export, GBC.std());
075        p.add(lbl, GBC.std());
076        p.add(GBC.glue(1, 0), GBC.std().fill(GBC.HORIZONTAL));
077        return p;
078    }
079
080    @Override
081    public Element export(ExportSupport support) throws IOException {
082        Element layerElem = support.createElement("layer");
083        layerElem.setAttribute("type", "imagery");
084        layerElem.setAttribute("version", "0.1");
085        ImageryPreferenceEntry e = new ImageryPreferenceEntry(layer.getInfo());
086        Map<String, String> data = new LinkedHashMap<>(StructUtils.serializeStruct(e, ImageryPreferenceEntry.class));
087        Utils.instanceOfThen(layer, AbstractTileSourceLayer.class, tsLayer -> {
088            data.putAll(tsLayer.getDisplaySettings().toPropertiesMap());
089            if (!tsLayer.getDisplaySettings().isAutoZoom()) {
090                data.put("zoom-level", Integer.toString(tsLayer.getZoomLevel()));
091            }
092        });
093        addAttributes(layerElem, data, support);
094        Utils.instanceOfThen(layer, AbstractTileSourceLayer.class, tsLayer -> {
095            OffsetBookmark offset = tsLayer.getDisplaySettings().getOffsetBookmark();
096            if (offset != null) {
097                Map<String, String> offsetProps = offset.toPropertiesMap();
098                Element offsetEl = support.createElement("offset");
099                layerElem.appendChild(offsetEl);
100                addAttributes(offsetEl, offsetProps, support);
101            }
102        });
103        ImageryFilterSettings filters = layer.getFilterSettings();
104        if (filters != null) {
105            Map<String, String> filterProps = new HashMap<>();
106            filters.getProcessors().stream()
107                    .flatMap(Utils.castToStream(SessionAwareReadApply.class))
108                    .forEach(proc -> filterProps.putAll(proc.toPropertiesMap()));
109            if (!filterProps.isEmpty()) {
110                Element filterEl = support.createElement("filters");
111                layerElem.appendChild(filterEl);
112                addAttributes(filterEl, filterProps, support);
113            }
114        }
115        return layerElem;
116    }
117
118    private static void addAttributes(Element element, Map<String, String> props, ExportSupport support) {
119        for (Map.Entry<String, String> entry : props.entrySet()) {
120            Element attrElem = support.createElement(entry.getKey());
121            element.appendChild(attrElem);
122            attrElem.appendChild(support.createTextNode(entry.getValue()));
123        }
124    }
125}