- Timestamp:
- 2015-05-19T20:54:26+02:00 (10 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java
r8389 r8397 63 63 64 64 public static class LIFOQueue extends LinkedBlockingDeque<Runnable> { 65 public LIFOQueue() { 66 super(); 67 } 68 65 69 public LIFOQueue(int capacity) { 66 70 super(capacity); … … 91 95 * and performance (we do want to have something to offer to worker threads before tasks will be resubmitted by class consumer) 92 96 */ 93 private static Executor DOWNLOAD_JOB_DISPATCHER = new ThreadPoolExecutor( 97 private static Executor DEFAULT_DOWNLOAD_JOB_DISPATCHER = new ThreadPoolExecutor( 94 98 2, // we have a small queue, so threads will be quickly started (threads are started only, when queue is full) 95 99 THREAD_LIMIT.get().intValue(), // do not this number of threads … … 114 118 private int readTimeout; 115 119 private Map<String, String> headers; 120 private Executor downloadJobExecutor; 116 121 117 122 /** … … 120 125 * @param readTimeout 121 126 * @param connectTimeout 127 * @param downloadJobExecutor 122 128 */ 123 129 public JCSCachedTileLoaderJob(ICacheAccess<K,V> cache, 124 130 int connectTimeout, int readTimeout, 125 Map<String, String> headers) { 131 Map<String, String> headers, 132 Executor downloadJobExecutor) { 126 133 127 134 this.cache = cache; … … 130 137 this.readTimeout = readTimeout; 131 138 this.headers = headers; 139 this.downloadJobExecutor = downloadJobExecutor; 140 } 141 142 /** 143 * @param cache cache instance that we will work on 144 * @param headers 145 * @param readTimeout 146 * @param connectTimeout 147 */ 148 public JCSCachedTileLoaderJob(ICacheAccess<K, V> cache, 149 int connectTimeout, int readTimeout, 150 Map<String, String> headers) { 151 this(cache, connectTimeout, readTimeout, 152 headers, DEFAULT_DOWNLOAD_JOB_DISPATCHER); 132 153 } 133 154 … … 240 261 */ 241 262 protected Executor getDownloadExecutor() { 242 return DOWNLOAD_JOB_DISPATCHER; 243 } 244 263 return downloadJobExecutor; 264 } 245 265 246 266 public void run() { … … 330 350 return true; 331 351 } 352 332 353 HttpURLConnection urlConn = getURLConnection(); 333 354 -
trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java
r8327 r8397 4 4 import java.io.IOException; 5 5 import java.util.Map; 6 import java.util.concurrent.ThreadPoolExecutor; 7 import java.util.concurrent.TimeUnit; 6 8 7 9 import org.apache.commons.jcs.access.behavior.ICacheAccess; … … 15 17 import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry; 16 18 import org.openstreetmap.josm.data.cache.JCSCacheManager; 19 import org.openstreetmap.josm.data.cache.JCSCachedTileLoaderJob.LIFOQueue; 17 20 import org.openstreetmap.josm.data.preferences.IntegerProperty; 18 21 … … 30 33 private Map<String, String> headers; 31 34 private TileLoaderListener listener; 32 p ublicstatic final String PREFERENCE_PREFIX = "imagery.tms.cache.";35 private static final String PREFERENCE_PREFIX = "imagery.tms.cache."; 33 36 // average tile size is about 20kb 34 37 public static final IntegerProperty MAX_OBJECTS_ON_DISK = new IntegerProperty(PREFERENCE_PREFIX + "max_objects_disk", 25000); // 25000 is around 500MB under this assumptions 35 38 39 /** 40 * overrides the THREAD_LIMIT in superclass, as we want to have separate limit and pool for TMS 41 */ 42 public static final IntegerProperty THREAD_LIMIT = new IntegerProperty("imagery.tms.tmsloader.maxjobs", 25); 43 44 /** 45 * separate from JCS thread pool for TMS loader, so we can have different thread pools for default JCS 46 * and for TMS imagery 47 */ 48 private static ThreadPoolExecutor DEFAULT_DOWNLOAD_JOB_DISPATCHER = getThreadPoolExecutor(); 49 50 private static ThreadPoolExecutor getThreadPoolExecutor() { 51 return new ThreadPoolExecutor( 52 THREAD_LIMIT.get().intValue(), // keep the thread number constant 53 THREAD_LIMIT.get().intValue(), // do not this number of threads 54 30, // keepalive for thread 55 TimeUnit.SECONDS, 56 // make queue of LIFO type - so recently requested tiles will be loaded first (assuming that these are which user is waiting to see) 57 new LIFOQueue() 58 /* keep the queue size fairly small, we do not want to 59 download a lot of tiles, that user is not seeing anyway */ 60 ); 61 } 62 63 private ThreadPoolExecutor downloadExecutor = DEFAULT_DOWNLOAD_JOB_DISPATCHER; 36 64 37 65 /** … … 58 86 @Override 59 87 public TileJob createTileLoaderJob(Tile tile) { 60 return new TMSCachedTileLoaderJob(listener, tile, cache, connectTimeout, readTimeout, headers); 88 return new TMSCachedTileLoaderJob(listener, tile, cache, 89 connectTimeout, readTimeout, headers, downloadExecutor); 61 90 } 62 91 … … 86 115 } 87 116 117 /** 118 * @return cache statistics as string 119 */ 88 120 public String getStats() { 89 121 return cache.getStats(); 90 122 } 123 124 /** 125 * Sets the download executor for this tile loader factory. Enables to use different queuing method 126 * for this factory. 127 * @param downloadExecutor 128 */ 129 public void setDownloadExecutor(ThreadPoolExecutor downloadExecutor) { 130 this.downloadExecutor = downloadExecutor; 131 } 132 133 /** 134 * @return Executor that handles the jobs for this tile loader 135 */ 136 public ThreadPoolExecutor getDownloadExecutor() { 137 return downloadExecutor; 138 } 139 140 /** 141 * cancels all outstanding tasks in the queue. This rollbacks the state of the tiles in the queue 142 * to loading = false / loaded = false 143 */ 144 public void cancelOutstandingTasks() { 145 for(Runnable elem: downloadExecutor.getQueue()) { 146 if (elem instanceof TMSCachedTileLoaderJob) { 147 TMSCachedTileLoaderJob loaderJob = (TMSCachedTileLoaderJob) elem; 148 if (downloadExecutor.remove(loaderJob)) { 149 Tile t = loaderJob.getTile(); 150 t.finishLoading(); 151 t.setLoaded(false); 152 } 153 } 154 } 155 } 156 91 157 } -
trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
r8389 r8397 15 15 import java.util.concurrent.Executor; 16 16 import java.util.concurrent.Semaphore; 17 import java.util.concurrent.ThreadPoolExecutor;18 import java.util.concurrent.TimeUnit;19 17 import java.util.logging.Level; 20 18 import java.util.logging.Logger; … … 99 97 100 98 /** 101 * overrides the THREAD_LIMIT in superclass, as we want to have separate limit and pool for TMS102 */103 public static final IntegerProperty THREAD_LIMIT = new IntegerProperty("imagery.tms.tmsloader.maxjobs", 25);104 105 /**106 * separate from JCS thread pool for TMS loader, so we can have different thread pools for default JCS107 * and for TMS imagery108 */109 private static ThreadPoolExecutor DOWNLOAD_JOB_DISPATCHER = getThreadPoolExecutor();110 111 private static ThreadPoolExecutor getThreadPoolExecutor() {112 return new ThreadPoolExecutor(113 THREAD_LIMIT.get().intValue(), // keep the thread number constant114 THREAD_LIMIT.get().intValue(), // do not this number of threads115 30, // keepalive for thread116 TimeUnit.SECONDS,117 // make queue of LIFO type - so recently requested tiles will be loaded first (assuming that these are which user is waiting to see)118 new LIFOQueue(5)119 /* keep the queue size fairly small, we do not want to120 download a lot of tiles, that user is not seeing anyway */121 );122 }123 124 /**125 99 * Reconfigures download dispatcher using current values of THREAD_LIMIT and HOST_LIMIT 126 100 */ 127 101 public static final void reconfigureDownloadDispatcher() { 128 102 HOST_LIMITS = new ConcurrentHashMap<>(); 129 DOWNLOAD_JOB_DISPATCHER = getThreadPoolExecutor();130 103 } 131 104 … … 139 112 * @param headers to be sent together with request 140 113 */ 141 public TMSCachedTileLoaderJob(TileLoaderListener listener, Tile tile, ICacheAccess<String, BufferedImageCacheEntry> cache, int connectTimeout, int readTimeout, 142 Map<String, String> headers) { 143 super(cache, connectTimeout, readTimeout, headers); 114 public TMSCachedTileLoaderJob(TileLoaderListener listener, Tile tile, 115 ICacheAccess<String, BufferedImageCacheEntry> cache, 116 int connectTimeout, int readTimeout, Map<String, String> headers, 117 Executor downloadExecutor) { 118 super(cache, connectTimeout, readTimeout, headers, downloadExecutor); 144 119 this.tile = tile; 145 120 if (listener != null) { … … 230 205 } 231 206 return false; 232 }233 234 @Override235 protected Executor getDownloadExecutor() {236 return DOWNLOAD_JOB_DISPATCHER;237 207 } 238 208 -
trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java
r8393 r8397 70 70 import org.openstreetmap.josm.gui.MapView; 71 71 import org.openstreetmap.josm.gui.MapView.LayerChangeListener; 72 import org.openstreetmap.josm.gui.NavigatableComponent.ZoomChangeListener; 72 73 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 73 74 import org.openstreetmap.josm.gui.dialogs.LayerListDialog; … … 91 92 * 92 93 */ 93 public class TMSLayer extends ImageryLayer implements ImageObserver, TileLoaderListener { 94 public class TMSLayer extends ImageryLayer implements ImageObserver, TileLoaderListener, ZoomChangeListener { 94 95 public static final String PREFERENCE_PREFIX = "imagery.tms"; 95 96 … … 104 105 public static final IntegerProperty PROP_MIN_ZOOM_LVL = new IntegerProperty(PREFERENCE_PREFIX + ".min_zoom_lvl", DEFAULT_MIN_ZOOM); 105 106 public static final IntegerProperty PROP_MAX_ZOOM_LVL = new IntegerProperty(PREFERENCE_PREFIX + ".max_zoom_lvl", DEFAULT_MAX_ZOOM); 106 //public static final BooleanProperty PROP_DRAW_DEBUG= new BooleanProperty(PREFERENCE_PREFIX +".draw_debug", false);107 public static final BooleanProperty PROP_ADD_TO_SLIPPYMAP_CHOOSER = new BooleanProperty(PREFERENCE_PREFIX +".add_to_slippymap_chooser", true);107 public static final BooleanProperty PROP_ADD_TO_SLIPPYMAP_CHOOSER = new BooleanProperty(PREFERENCE_PREFIX + 108 ".add_to_slippymap_chooser", true); 108 109 public static final StringProperty PROP_TILECACHE_DIR; 109 110 … … 118 119 } 119 120 121 /** 122 * Interface for creating TileLoaders, ie. classes responsible for loading tiles on map 123 * 124 */ 120 125 public interface TileLoaderFactory { 126 /** 127 * @param listener object that will be notified, when tile has finished loading 128 * @return TileLoader that will notify the listener 129 */ 121 130 TileLoader makeTileLoader(TileLoaderListener listener); 131 132 /** 133 * @param listener object that will be notified, when tile has finished loading 134 * @param headers HTTP headers that should be sent by TileLoader to tile server 135 * @return TileLoader that will notify the listener 136 */ 122 137 TileLoader makeTileLoader(TileLoaderListener listener, Map<String, String> headers); 123 138 } … … 189 204 * method. 190 205 * 191 * @param monitor 192 * @see OsmFileCacheTileLoader#clearCache(org.openstreetmap.gui.jmapviewer.interfaces.TileSource, org.openstreetmap.gui.jmapviewer.interfaces.TileClearController) 193 */ 194 void clearTileCache(ProgressMonitor monitor) { 206 * @param monitor not used in this implementation - as cache clear is instaneus 207 */ 208 public void clearTileCache(ProgressMonitor monitor) { 195 209 tileCache.clear(); 196 210 if (tileLoader instanceof CachedTileLoader) { 197 211 ((CachedTileLoader)tileLoader).clearCache(tileSource); 198 212 } 213 redraw(); 199 214 } 200 215 … … 225 240 * @see MapFrame#repaint() 226 241 */ 227 void redraw() { 242 protected void redraw() { 228 243 needRedraw = true; 229 244 Main.map.repaint(); 230 245 } 231 246 232 static int checkMaxZoomLvl(int maxZoomLvl, TileSource ts) { 247 protected static int checkMaxZoomLvl(int maxZoomLvl, TileSource ts) { 233 248 if(maxZoomLvl > MAX_ZOOM) { 234 249 maxZoomLvl = MAX_ZOOM; … … 248 263 249 264 public static void setMaxZoomLvl(int maxZoomLvl) { 250 maxZoomLvl =checkMaxZoomLvl(maxZoomLvl, null);251 PROP_MAX_ZOOM_LVL.put( maxZoomLvl);265 Integer newMaxZoom = Integer.valueOf(checkMaxZoomLvl(maxZoomLvl, null)); 266 PROP_MAX_ZOOM_LVL.put(newMaxZoom); 252 267 } 253 268 … … 342 357 return t; 343 358 } else if (info.getImageryType() == ImageryType.BING) { 344 //return new CachedAttributionBingAerialTileSource(info.getId());345 359 return new CachedAttributionBingAerialTileSource(info); 346 360 } else if (info.getImageryType() == ImageryType.SCANEX) { 347 //return new ScanexTileSource(info.getName(), info.getUrl(), info.getId(), info.getMaxZoom());348 361 return new ScanexTileSource(info); 349 362 } … … 385 398 } 386 399 387 // FIXME: tileCache = new MemoryTileCache();388 400 tileLoader = loaderFactory.makeTileLoader(this, headers); 389 401 if (tileLoader instanceof TMSCachedTileLoader) { … … 464 476 throw new IllegalStateException("Cannot create TMSLayer with non-TMS ImageryInfo"); 465 477 initTileSource(source); 478 479 MapView.addZoomChangeListener(this); 466 480 } 467 481 … … 538 552 })); 539 553 540 /* FIXME541 554 tileOptionMenu.add(new JMenuItem(new AbstractAction( 542 555 tr("Request Update")) { 543 556 public void actionPerformed(ActionEvent ae) { 544 557 if (clickedTile != null) { 545 clickedTile. requestUpdate();546 redraw();547 } 548 } 549 })); */558 clickedTile.setLoaded(false); 559 tileLoader.createTileLoaderJob(clickedTile).submit(); 560 } 561 } 562 })); 550 563 551 564 tileOptionMenu.add(new JMenuItem(new AbstractAction( … … 590 603 @Override 591 604 public void actionPerformed(ActionEvent ae) { 592 double new _factor = Math.sqrt(getScaleFactor(currentZoomLevel));593 Main.map.mapView.zoomToFactor(new _factor);605 double newFactor = Math.sqrt(getScaleFactor(currentZoomLevel)); 606 Main.map.mapView.zoomToFactor(newFactor); 594 607 redraw(); 595 608 } … … 647 660 if (oldLayer == TMSLayer.this) { 648 661 Main.map.mapView.removeMouseListener(adapter); 662 MapView.removeZoomChangeListener(TMSLayer.this); 649 663 MapView.removeLayerChangeListener(this); 650 664 } … … 653 667 } 654 668 655 void zoomChanged() { 669 /** 670 * This fires every time the user changes the zoom, but also (due to ZoomChangeListener) - on all 671 * changes to visible map (panning/zooming) 672 */ 673 @Override 674 public void zoomChanged() { 656 675 if (Main.isDebugEnabled()) { 657 676 Main.debug("zoomChanged(): " + currentZoomLevel); 658 677 } 659 678 needRedraw = true; 660 } 661 662 int getMaxZoomLvl() { 679 if (tileLoader instanceof TMSCachedTileLoader) { 680 ((TMSCachedTileLoader) tileLoader).cancelOutstandingTasks(); 681 } 682 } 683 684 protected int getMaxZoomLvl() { 663 685 if (info.getMaxZoom() != 0) 664 686 return checkMaxZoomLvl(info.getMaxZoom(), tileSource); … … 667 689 } 668 690 669 int getMinZoomLvl() { 691 protected int getMinZoomLvl() { 670 692 return getMinZoomLvl(tileSource); 671 693 } … … 674 696 * Zoom in, go closer to map. 675 697 * 676 * @return true, if zoom increasing was successful l, false othervise698 * @return true, if zoom increasing was successful, false otherwise 677 699 */ 678 700 public boolean zoomIncreaseAllowed() { … … 742 764 * into the tileCache. 743 765 */ 744 Tile tempCornerTile(Tile t) { 766 private Tile tempCornerTile(Tile t) { 745 767 int x = t.getXtile() + 1; 746 768 int y = t.getYtile() + 1; … … 752 774 } 753 775 754 Tile getOrCreateTile(int x, int y, int zoom) { 776 private Tile getOrCreateTile(int x, int y, int zoom) { 755 777 Tile tile = getTile(x, y, zoom); 756 778 if (tile == null) { … … 766 788 * already in the cache. 767 789 */ 768 Tile getTile(int x, int y, int zoom) { 790 private Tile getTile(int x, int y, int zoom) { 769 791 int max = 1 << zoom; 770 792 if (x < 0 || x >= max || y < 0 || y >= max) … … 773 795 } 774 796 775 boolean loadTile(Tile tile, boolean force) { 797 private boolean loadTile(Tile tile, boolean force) { 776 798 if (tile == null) 777 799 return false; … … 784 806 } 785 807 786 void loadAllTiles(boolean force) { 808 private void loadAllTiles(boolean force) { 787 809 MapView mv = Main.map.mapView; 788 810 EastNorth topLeft = mv.getEastNorth(0, 0); … … 800 822 } 801 823 802 void loadAllErrorTiles(boolean force) { 824 private void loadAllErrorTiles(boolean force) { 803 825 MapView mv = Main.map.mapView; 804 826 EastNorth topLeft = mv.getEastNorth(0, 0); … … 821 843 } 822 844 823 boolean imageLoaded(Image i) { 845 private boolean imageLoaded(Image i) { 824 846 if (i == null) 825 847 return false; … … 837 859 * @return the image of the tile or null. 838 860 */ 839 Image getLoadedTileImage(Tile tile) { 861 private Image getLoadedTileImage(Tile tile) { 840 862 if (!tile.isLoaded()) 841 863 return null; … … 846 868 } 847 869 848 LatLon tileLatLon(Tile t) { 870 private LatLon tileLatLon(Tile t) { 849 871 int zoom = t.getZoom(); 850 872 return new LatLon(tileSource.tileYToLat(t.getYtile(), zoom), … … 852 874 } 853 875 854 Rectangle tileToRect(Tile t1) { 876 private Rectangle tileToRect(Tile t1) { 855 877 /* 856 878 * We need to get a box in which to draw, so advance by one tile in … … 870 892 // 'border' is the screen cordinates that need to be drawn. 871 893 // We must not draw outside of it. 872 void drawImageInside(Graphics g, Image sourceImg, Rectangle source, Rectangle border) { 894 private void drawImageInside(Graphics g, Image sourceImg, Rectangle source, Rectangle border) { 873 895 Rectangle target = source; 874 896 … … 931 953 // drawn currently. If drawing the displayZoomLevel, 932 954 // border is null and we draw the entire tile set. 933 List<Tile> paintTileImages(Graphics g, TileSet ts, int zoom, Tile border) { 955 private List<Tile> paintTileImages(Graphics g, TileSet ts, int zoom, Tile border) { 934 956 if (zoom <= 0) return Collections.emptyList(); 935 957 Rectangle borderRect = null; … … 962 984 } 963 985 964 void myDrawString(Graphics g, String text, int x, int y) { 986 private void myDrawString(Graphics g, String text, int x, int y) { 965 987 Color oldColor = g.getColor(); 966 988 g.setColor(Color.black); … … 970 992 } 971 993 972 void paintTileText(TileSet ts, Tile tile, Graphics g, MapView mv, int zoom, Tile t) { 994 private void paintTileText(TileSet ts, Tile tile, Graphics g, MapView mv, int zoom, Tile t) { 973 995 int fontHeight = g.getFontMetrics().getHeight(); 974 996 if (tile == null) … … 1066 1088 * Create a TileSet by EastNorth bbox taking a layer shift in account 1067 1089 */ 1068 TileSet(EastNorth topLeft, EastNorth botRight, int zoom) { 1090 private TileSet(EastNorth topLeft, EastNorth botRight, int zoom) { 1069 1091 this(getShiftedLatLon(topLeft), getShiftedLatLon(botRight),zoom); 1070 1092 } … … 1073 1095 * Create a TileSet by known LatLon bbox without layer shift correction 1074 1096 */ 1075 TileSet(LatLon topLeft, LatLon botRight, int zoom) { 1097 private TileSet(LatLon topLeft, LatLon botRight, int zoom) { 1076 1098 this.zoom = zoom; 1077 1099 if (zoom == 0) … … 1107 1129 } 1108 1130 1109 boolean tooSmall() { 1131 private boolean tooSmall() { 1110 1132 return this.tilesSpanned() < 2.1; 1111 1133 } 1112 1134 1113 boolean tooLarge() { 1135 private boolean tooLarge() { 1114 1136 return this.tilesSpanned() > 10; 1115 1137 } 1116 1138 1117 boolean insane() { 1139 private boolean insane() { 1118 1140 return this.tilesSpanned() > 100; 1119 1141 } 1120 1142 1121 double tilesSpanned() { 1143 private double tilesSpanned() { 1122 1144 return Math.sqrt(1.0 * this.size()); 1123 1145 } 1124 1146 1125 int size() { 1147 private int size() { 1126 1148 int x_span = x1 - x0 + 1; 1127 1149 int y_span = y1 - y0 + 1; … … 1133 1155 * already in the tileCache. 1134 1156 */ 1135 List<Tile> allExistingTiles() { 1157 private List<Tile> allExistingTiles() { 1136 1158 return this.__allTiles(false); 1137 1159 } 1138 1160 1139 List<Tile> allTilesCreate() { 1161 private List<Tile> allTilesCreate() { 1140 1162 return this.__allTiles(true); 1141 1163 } … … 1171 1193 } 1172 1194 1173 void loadAllTiles(boolean force) { 1195 private void loadAllTiles(boolean force) { 1174 1196 if (!autoLoad && !force) 1175 1197 return; … … 1179 1201 } 1180 1202 1181 void loadAllErrorTiles(boolean force) { 1203 private void loadAllErrorTiles(boolean force) { 1182 1204 if (!autoLoad && !force) 1183 1205 return; … … 1418 1440 * user right-clicks on the map. 1419 1441 */ 1420 Tile getTileForPixelpos(int px, int py) { 1442 private Tile getTileForPixelpos(int px, int py) { 1421 1443 if (Main.isDebugEnabled()) { 1422 1444 Main.debug("getTileForPixelpos("+px+", "+py+")");
Note:
See TracChangeset
for help on using the changeset viewer.