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