配置异步多线程
@Configuration
@EnableAsync
public class AsyncThreadConfiguration implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(SuperMapTool.CorePoolSize);
executor.setMaxPoolSize(32);
executor.setQueueCapacity(256);
executor.setThreadNamePrefix(SuperMapTool.ThreadNamePrefix);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
由于Map对象非线程安全,前端每一个瓦片请求,在后端都需要开启一个线程来异步处理Map生成对应瓦片BufferedImage对象,避免线程堵塞。
配置Map线程池
public void initMapPools() {
for (int i = 1; i < SuperMapTool.CorePoolSize + 1; i++) {
Map map = new Map(m_workspace);
boolean isOpen = map.open(mapName);
logger.info(SuperMapTool.ThreadNamePrefix + i + "=" + isOpen);
mapPools.put(SuperMapTool.ThreadNamePrefix + i, map);
如果每一个前端瓦片请求,后端都打开地图,那么特别耗时,影响出图性能。所以设计一个地图的线程池,用线程名称作为key,将map作为value存起来,程序启动时就完成线程池hashmap的初始化。这样前端请求时根据线程名称取map对象,将大大提高处理效率,空间换时间。
Map生成webp瓦片数据
@Async
public CompletableFuture<byte[]> makeTile(int z,int x,int y) {
try {
Geometry geometry = SuperMapTool.xyz2prj3857(z,x,y);
Map mMap = mapPools.get(Thread.currentThread().getName());
mMap.setScale(initScales().getOrDefault(z, 0.0));
mMap.setCenter(geometry.getInnerPoint());
mMap.setCustomBoundsEnabled(true);
mMap.setCustomBounds(geometry.getBounds());
mMap.setImageSize(new Dimension(256, 256));
BufferedImage image = mMap.outputMapToBitmap(true);
geometry.dispose();
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(image, "webp", out);
byte[] bytes = out.toByteArray();
image = null;
out.close();
return CompletableFuture.completedFuture(bytes);
} catch (Exception e) {
logger.error("makeTile异常=" + e.getMessage());
return null;
层级Z与比例尺的对应表,可以参考zoom2scale.txt文件。
根据比例尺、范围和中心点就可以确定一个瓦片数据,将Map对应生成BufferedImage对象。
借助于webp-imageio三方库,将BufferedImage写为webp格式二进制数据,可以确保质量不丢失的情况,体积相比png减少了8倍,加快网络传输,减少内存占用。