source: josm/trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java@ 13818

Last change on this file since 13818 was 13733, checked in by wiktorn, 6 years ago

Imagery definition refactor

Extend imagery definitions by:

  • allowing setting default layers for WMS_ENDPOINT and WMTS
  • allowing setting minimum expires time for tile for this imagery
  • allowing setting custom headers that will be sent for all requests

(get map, get capabilities) for this imagery

Additional changes in code:

  • use TileJobOptions to pass miscellaneous options to loaders
  • refactor WMSImagery to use SAX parser

See: #15981, #7953, #16224, #15940, #16249

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.imagery;
3
4import java.util.concurrent.ThreadPoolExecutor;
5import java.util.concurrent.TimeUnit;
6
7import org.apache.commons.jcs.access.behavior.ICacheAccess;
8import org.openstreetmap.gui.jmapviewer.Tile;
9import org.openstreetmap.gui.jmapviewer.interfaces.CachedTileLoader;
10import org.openstreetmap.gui.jmapviewer.interfaces.TileJob;
11import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
12import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener;
13import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
14import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;
15import org.openstreetmap.josm.data.cache.HostLimitQueue;
16import org.openstreetmap.josm.data.preferences.IntegerProperty;
17import org.openstreetmap.josm.tools.CheckParameterUtil;
18import org.openstreetmap.josm.tools.Utils;
19
20/**
21 * Wrapper class that bridges between JCS cache and Tile Loaders
22 *
23 * @author Wiktor Niesiobędzki
24 */
25public class TMSCachedTileLoader implements TileLoader, CachedTileLoader {
26
27 protected final ICacheAccess<String, BufferedImageCacheEntry> cache;
28 protected final TileLoaderListener listener;
29
30 /**
31 * overrides the THREAD_LIMIT in superclass, as we want to have separate limit and pool for TMS
32 */
33
34 public static final IntegerProperty THREAD_LIMIT = new IntegerProperty("imagery.tms.tmsloader.maxjobs", 25);
35
36 /**
37 * Limit definition for per host concurrent connections
38 */
39 public static final IntegerProperty HOST_LIMIT = new IntegerProperty("imagery.tms.tmsloader.maxjobsperhost", 6);
40
41 /**
42 * separate from JCS thread pool for TMS loader, so we can have different thread pools for default JCS
43 * and for TMS imagery
44 */
45 private static final ThreadPoolExecutor DEFAULT_DOWNLOAD_JOB_DISPATCHER = getNewThreadPoolExecutor("TMS-downloader-%d");
46
47 private ThreadPoolExecutor downloadExecutor = DEFAULT_DOWNLOAD_JOB_DISPATCHER;
48 protected final TileJobOptions options;
49
50 /**
51 * Constructor
52 * @param listener called when tile loading has finished
53 * @param cache of the cache
54 * @param options tile job options
55 */
56 public TMSCachedTileLoader(TileLoaderListener listener, ICacheAccess<String, BufferedImageCacheEntry> cache,
57 TileJobOptions options) {
58 CheckParameterUtil.ensureParameterNotNull(cache, "cache");
59 this.cache = cache;
60 this.options = options;
61 this.listener = listener;
62 }
63
64 /**
65 * @param nameFormat see {@link Utils#newThreadFactory(String, int)}
66 * @param workers number of worker thread to keep
67 * @return new ThreadPoolExecutor that will use a @see HostLimitQueue based queue
68 */
69 public static ThreadPoolExecutor getNewThreadPoolExecutor(String nameFormat, int workers) {
70 HostLimitQueue workQueue = new HostLimitQueue(HOST_LIMIT.get().intValue());
71 ThreadPoolExecutor executor = new ThreadPoolExecutor(
72 0, // 0 so for unused thread pools threads will eventually die, freeing also the threadpool
73 workers, // do not this number of threads
74 300, // keepalive for thread
75 TimeUnit.SECONDS,
76 workQueue,
77 Utils.newThreadFactory(nameFormat, Thread.NORM_PRIORITY)
78 );
79 workQueue.setExecutor(executor);
80 return executor;
81 }
82
83 /**
84 * @param name name of threads
85 * @return new ThreadPoolExecutor that will use a @see HostLimitQueue based queue, with default number of threads
86 */
87 public static ThreadPoolExecutor getNewThreadPoolExecutor(String name) {
88 return getNewThreadPoolExecutor(name, THREAD_LIMIT.get().intValue());
89 }
90
91 @Override
92 public TileJob createTileLoaderJob(Tile tile) {
93 return new TMSCachedTileLoaderJob(
94 listener,
95 tile,
96 cache,
97 options,
98 getDownloadExecutor());
99 }
100
101 @Override
102 public void clearCache(TileSource source) {
103 this.cache.remove(source.getName() + ':');
104 }
105
106 /**
107 * @return cache statistics as string
108 */
109 public String getStats() {
110 return cache.getStats();
111 }
112
113 /**
114 * cancels all outstanding tasks in the queue. This rollbacks the state of the tiles in the queue
115 * to loading = false / loaded = false
116 */
117 @Override
118 public void cancelOutstandingTasks() {
119 for (Runnable r: downloadExecutor.getQueue()) {
120 if (downloadExecutor.remove(r) && r instanceof TMSCachedTileLoaderJob) {
121 ((TMSCachedTileLoaderJob) r).handleJobCancellation();
122 }
123 }
124 }
125
126 @Override
127 public boolean hasOutstandingTasks() {
128 return downloadExecutor.getTaskCount() > downloadExecutor.getCompletedTaskCount();
129 }
130
131 /**
132 * Sets the download executor that will be used to download tiles instead of default one.
133 * You can use {@link #getNewThreadPoolExecutor} to create a new download executor with separate
134 * queue from default.
135 *
136 * @param downloadExecutor download executor that will be used to download tiles
137 */
138 public void setDownloadExecutor(ThreadPoolExecutor downloadExecutor) {
139 this.downloadExecutor = downloadExecutor;
140 }
141
142 /**
143 * @return download executor that is used by this factory
144 */
145 public ThreadPoolExecutor getDownloadExecutor() {
146 return downloadExecutor;
147 }
148}
Note: See TracBrowser for help on using the repository browser.