org.mapfish.print.map.ParallelMapTileLoader Maven / Gradle / Ivy
/*
* Copyright (C) 2013 Camptocamp
*
* This file is part of MapFish Print
*
* MapFish Print is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MapFish Print is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MapFish Print. If not, see .
*/
package org.mapfish.print.map;
import org.mapfish.print.RenderingContext;
import org.pvalsecc.concurrent.BlockingSimpleTarget;
import org.pvalsecc.concurrent.OrderedResultsExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfContentByte;
/**
* An instance of this class is in charge of loading in parallel the tiles of a
* single !map block.
*
* Since a lot of stuff is done in //, a lot of care has to be put on protecting
* the shared resources. One of the big ones is the DirectContent (dc) or the
* PDFWriter. For those, a lock on context.getPdfLock() is used.
*
* This class uses a global {@link org.pvalsecc.concurrent.OrderedResultsExecutor} to
* do the things in // and a {@link org.pvalsecc.concurrent.BlockingSimpleTarget} to
* know when everything is finished.
*/
public class ParallelMapTileLoader implements OrderedResultsExecutor.ResultCollector {
private final PdfContentByte dc;
private RenderingContext context;
/**
* Reference on the global executor to use.
*/
private final OrderedResultsExecutor executor;
/**
* Target used to know when all the tiles are read and rendered.
*/
private final BlockingSimpleTarget target = new BlockingSimpleTarget("mapTiles");
/**
* Number of tiles scheduled
*/
private int nbTiles = 0;
public ParallelMapTileLoader(RenderingContext context, PdfContentByte dc) {
executor = context.getConfig().getMapRenderingExecutor();
this.dc = dc;
this.context = context;
}
/**
* Schedule a tile to be loaded and rendered using the given task.
*/
public void addTileToLoad(MapTileTask task) {
nbTiles++;
if (executor != null) {
executor.addTask(task, this);
} else {
//no parallel loading... do it right away
task.process();
handle(task);
}
}
/**
* Wait for all the tiles to be loaded and rendered.
*/
public void waitForCompletion() {
target.setTarget(nbTiles);
try {
target.waitForCompletion(TimeUnit.MINUTES.toMillis(context.getConfig().getPrintTimeoutMinutes()));
} catch (TimeoutException e) {
throw new RuntimeException(e);
}
}
/**
* Called each time a result is available, in the order the tiles were
* scheduled to be loaded. For one PDF file, not called in //.
*/
public void handle(MapTileTask mapTileTaskResult) {
try {
if (!mapTileTaskResult.handleException(context)) {
synchronized (context.getPdfLock()) { //tiles may be currently loading in another thread
dc.saveState();
try {
mapTileTaskResult.renderOnPdf(dc);
} catch (DocumentException e) {
context.addError(e);
} finally {
dc.restoreState();
}
}
}
} finally {
target.addDone(1);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy