001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.io.imagery;
003
004import java.awt.image.BufferedImage;
005import java.io.ByteArrayInputStream;
006import java.io.ByteArrayOutputStream;
007import java.io.IOException;
008import java.net.URL;
009import java.text.MessageFormat;
010import java.util.ArrayList;
011import java.util.List;
012import java.util.StringTokenizer;
013
014import org.openstreetmap.josm.Main;
015import org.openstreetmap.josm.data.preferences.StringProperty;
016import org.openstreetmap.josm.gui.MapView;
017import org.openstreetmap.josm.gui.layer.WMSLayer;
018import org.openstreetmap.josm.tools.ImageProvider;
019import org.openstreetmap.josm.tools.Utils;
020
021public class HTMLGrabber extends WMSGrabber {
022    public static final StringProperty PROP_BROWSER = new StringProperty("imagery.wms.browser", "webkit-image {0}");
023
024    public HTMLGrabber(MapView mv, WMSLayer layer, boolean localOnly) {
025        super(mv, layer, localOnly);
026    }
027
028    @Override
029    protected BufferedImage grab(WMSRequest request, URL url, int attempt) throws IOException {
030        String urlstring = url.toExternalForm();
031
032        Main.info("Grabbing HTML " + (attempt > 1? "(attempt " + attempt + ") ":"") + url);
033
034        List<String> cmdParams = new ArrayList<>();
035        StringTokenizer st = new StringTokenizer(MessageFormat.format(PROP_BROWSER.get(), urlstring));
036        while (st.hasMoreTokens()) {
037            cmdParams.add(st.nextToken());
038        }
039
040        ProcessBuilder builder = new ProcessBuilder( cmdParams);
041
042        Process browser;
043        try {
044            browser = builder.start();
045        } catch (IOException ioe) {
046            throw new IOException("Could not start browser. Please check that the executable path is correct.\n" + ioe.getMessage(), ioe);
047        }
048
049        ByteArrayOutputStream baos = new ByteArrayOutputStream();
050        Utils.copyStream(browser.getInputStream(), baos);
051        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
052        BufferedImage img = layer.normalizeImage(ImageProvider.read(bais, true, WMSLayer.PROP_ALPHA_CHANNEL.get()));
053        bais.reset();
054        layer.cache.saveToCache(layer.isOverlapEnabled()?img:null, bais, Main.getProjection(), request.getPixelPerDegree(), b.minEast, b.minNorth);
055
056        return img;
057    }
058}