001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.plugins.streetside.cubemap;
003
004import java.awt.image.BufferedImage;
005import java.text.MessageFormat;
006import java.util.List;
007import java.util.Objects;
008import java.util.concurrent.Callable;
009import java.util.concurrent.CopyOnWriteArrayList;
010
011import javax.imageio.ImageIO;
012
013import org.apache.log4j.Logger;
014import org.openstreetmap.josm.plugins.streetside.cache.StreetsideCache;
015import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
016import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL;
017
018import us.monoid.web.Resty;
019
020public class TileDownloadingTask implements Callable<String> {
021
022  final static Logger logger = Logger.getLogger(TileDownloadingTask.class);
023
024        private String tileId;
025        private final long startTime = System.currentTimeMillis();
026        private StreetsideCache cache;
027        protected CubemapBuilder cb;
028
029        /**
030           * Listeners of the class.
031           */
032    private final List<ITileDownloadingTaskListener> listeners = new CopyOnWriteArrayList<>();
033
034        boolean cancelled = false;
035
036        public TileDownloadingTask(String id) {
037                tileId = id;
038                cb = CubemapBuilder.getInstance();
039                addListener(CubemapBuilder.getInstance());
040        }
041
042        /**
043           * Adds a new listener.
044           *
045           * @param lis Listener to be added.
046           */
047        public final void addListener(final ITileDownloadingTaskListener lis) {
048            listeners.add(lis);
049        }
050
051        /**
052         * @return the tileId
053         */
054        public String getId() {
055                return tileId;
056        }
057
058        /**
059         * @param id the tileId to set
060         */
061        public void setId(String id) {
062                tileId = id;
063        }
064
065        /**
066         * @return the cache
067         */
068        public StreetsideCache getCache() {
069                return cache;
070        }
071
072        /**
073         * @param cache the cache to set
074         */
075        public void setCache(StreetsideCache cache) {
076                this.cache = cache;
077        }
078
079        /**
080         * @return the cb
081         */
082        public CubemapBuilder getCb() {
083                return cb;
084        }
085
086        /**
087         * @param cb the cb to set
088         */
089        public void setCb(CubemapBuilder cb) {
090                this.cb = cb;
091        }
092
093        /**
094         * @param cancelled the cancelled to set
095         */
096        public void setCancelled(boolean cancelled) {
097                this.cancelled = cancelled;
098        }
099
100        @Override
101        public String call() throws Exception {
102
103                BufferedImage img = ImageIO.read(new Resty().bytes(
104                                StreetsideURL.VirtualEarth.streetsideTile(tileId, false).toExternalForm())
105                                .stream());
106
107                if (img == null) {
108                        logger.error("Download of BufferedImage " + tileId + " is null!");
109                }
110
111                CubemapBuilder.getInstance().getTileImages().put(tileId, img);
112
113                fireTileAdded(tileId);
114
115                if (StreetsideProperties.DEBUGING_ENABLED.get()) {
116                  long endTime = System.currentTimeMillis();
117            long runTime = (endTime-startTime)/1000;
118            logger.debug(MessageFormat.format("Loaded image for {0} in {1} seconds.", tileId, runTime));
119                }
120
121                return tileId;
122        }
123
124        private void fireTileAdded(String id) {
125            listeners.stream().filter(Objects::nonNull).forEach(lis -> lis.tileAdded(id));
126        }
127}