use of org.geotoolkit.process.ProcessListener in project geotoolkit by Geomatys.
the class AbstractTileGenerator method generate.
@Override
public void generate(TileMatrixSet pyramid, Envelope env, NumberRange resolutions, ProcessListener listener) throws DataStoreException, InterruptedException {
if (env != null) {
try {
env = Envelopes.transform(env, pyramid.getCoordinateReferenceSystem());
} catch (TransformException ex) {
throw new DataStoreException(ex.getMessage(), ex);
}
}
final long total = TileMatrices.countTiles(pyramid, env, resolutions);
final AtomicLong al = new AtomicLong();
// generate mosaic in resolution order
// this order allows the pyramid to be used at high scales until she is not completed.
final List<TileMatrix> mosaics = new ArrayList<>(pyramid.getTileMatrices());
mosaics.sort((TileMatrix o1, TileMatrix o2) -> Double.compare(o2.getScale(), o1.getScale()));
for (final TileMatrix mosaic : mosaics) {
if (resolutions == null || resolutions.containsAny(mosaic.getScale())) {
final Rectangle rect;
try {
rect = TileMatrices.getTilesInEnvelope(mosaic, env);
} catch (NoSuchDataException ex) {
continue;
}
final long nbTile = ((long) rect.width) * ((long) rect.height);
final long eventstep = Math.min(1000, Math.max(1, nbTile / 100l));
Stream<Tile> stream = LongStream.range(0, nbTile).parallel().mapToObj(new LongFunction<Tile>() {
@Override
public Tile apply(long value) {
final long x = rect.x + (value % rect.width);
final long y = rect.y + (value / rect.width);
Tile data = null;
try {
// do not regenerate existing tiles
// if (!mosaic.isMissing((int)x, (int)y)) return;
final Point coord = new Point((int) x, (int) y);
try {
data = generateTile(pyramid, mosaic, coord);
} catch (Exception ex) {
data = TileInError.create(coord, null, ex);
}
} finally {
long v = al.incrementAndGet();
if (listener != null & (v % eventstep == 0)) {
listener.progressing(new ProcessEvent(DUMMY, v + "/" + total + " mosaic=" + mosaic.getIdentifier() + " scale=" + mosaic.getScale(), (float) ((((double) v) / ((double) total)) * 100.0)));
}
}
return data;
}
}).filter(this::emptyFilter);
batchWrite(stream, mosaic, listener == null ? null : err -> listener.progressing(new ProcessEvent(DUMMY, "Error while writing tile batch", (float) ((((double) al.get()) / ((double) total)) * 100.0))), 200);
long v = al.get();
if (listener != null) {
listener.progressing(new ProcessEvent(DUMMY, v + "/" + total + " mosaic=" + mosaic.getIdentifier() + " scale=" + mosaic.getScale(), (float) ((((double) v) / ((double) total)) * 100.0)));
}
}
}
}
use of org.geotoolkit.process.ProcessListener in project geotoolkit by Geomatys.
the class CoverageTileGenerator method generate.
@Override
public void generate(TileMatrixSet pyramid, Envelope env, NumberRange resolutions, ProcessListener listener) throws DataStoreException, InterruptedException {
if (!coverageIsHomogeneous) {
super.generate(pyramid, env, resolutions, listener);
return;
}
/*
We can generate the pyramid starting from the lowest level then going up
using the previously generated level.
*/
if (env != null) {
try {
CoordinateReferenceSystem targetCrs = pyramid.getCoordinateReferenceSystem();
Envelope baseEnv = env;
env = Envelopes.transform(env, targetCrs);
if (resolutions != null) {
double[] minres = new double[] { resolutions.getMinDouble(), resolutions.getMinDouble() };
double[] maxres = new double[] { resolutions.getMaxDouble(), resolutions.getMaxDouble() };
minres = ReferencingUtilities.convertResolution(baseEnv, minres, targetCrs, null);
maxres = ReferencingUtilities.convertResolution(baseEnv, maxres, targetCrs, null);
resolutions = NumberRange.create(minres[0], true, maxres[0], true);
}
} catch (TransformException ex) {
throw new DataStoreException(ex.getMessage(), ex);
}
}
// generate lower level from data
final TileMatrix[] mosaics = pyramid.getTileMatrices().toArray(new TileMatrix[0]);
Arrays.sort(mosaics, (TileMatrix o1, TileMatrix o2) -> Double.compare(o1.getScale(), o2.getScale()));
final long total = TileMatrices.countTiles(pyramid, env, resolutions);
final double totalAsDouble = total;
final AtomicLong al = new AtomicLong();
final Supplier<Float> progress = () -> (float) (al.get() / totalAsDouble * 100.0);
GridCoverageResource resourceCenter = this.resource;
GridCoverageResource resourceBorder = this.resource;
for (final TileMatrix mosaic : mosaics) {
if (resolutions == null || resolutions.contains(mosaic.getScale())) {
final Rectangle rect;
try {
rect = TileMatrices.getTilesInEnvelope(mosaic, env);
} catch (NoSuchDataException ex) {
continue;
}
final GridCoverageResource sourceCenter = resourceCenter;
final GridCoverageResource sourceBorder = resourceBorder;
final long nbTile = ((long) rect.width) * ((long) rect.height);
final long eventstep = Math.min(1000, Math.max(1, nbTile / 100l));
Stream<Tile> stream = LongStream.range(0, nbTile).parallel().mapToObj(new LongFunction<Tile>() {
@Override
public Tile apply(long value) {
final long x = rect.x + (value % rect.width);
final long y = rect.y + (value / rect.width);
final boolean isBorderTile = (x == rect.x || x == (rect.x + rect.width - 1)) || (y == rect.y || y == (rect.y + rect.height - 1));
Tile data = null;
try {
if (skipExistingTiles && !mosaic.isMissing((int) x, (int) y)) {
// tile already exist
return null;
}
final Point coord = new Point((int) x, (int) y);
try {
data = generateTile(pyramid, mosaic, coord, isBorderTile ? sourceBorder : sourceCenter);
} catch (Exception ex) {
data = TileInError.create(coord, null, ex);
}
} finally {
long v = al.incrementAndGet();
if (listener != null & (v % eventstep == 0)) {
listener.progressing(new ProcessEvent(DUMMY, v + "/" + total + " mosaic=" + mosaic.getIdentifier() + " scale=" + mosaic.getScale(), progress.get()));
}
}
return data;
}
}).filter(this::emptyFilter);
batchWrite(stream, mosaic, listener == null ? null : err -> listener.progressing(new ProcessEvent(DUMMY, "Error while writing tile batch", progress.get(), err)), 200);
long v = al.get();
if (listener != null) {
listener.progressing(new ProcessEvent(DUMMY, v + "/" + total + " mosaic=" + mosaic.getIdentifier() + " scale=" + mosaic.getScale(), progress.get()));
}
if (!generateFromSource) {
// modify context
final DefaultTileMatrixSet pm = new DefaultTileMatrixSet(pyramid.getCoordinateReferenceSystem());
pm.getMosaicsInternal().add(mosaic);
final InMemoryTiledGridCoverageResource r = new InMemoryTiledGridCoverageResource(NamesExt.create("test"));
r.setSampleDimensions(resourceCenter.getSampleDimensions());
r.getTileMatrixSets().add(pm);
// we must still use the original resource for generation because
// lower level tiles may not be sufficient to generate border tiles
final AggregatedCoverageResource aggregated = new AggregatedCoverageResource();
aggregated.setMode(AggregatedCoverageResource.Mode.ORDER);
aggregated.add(r);
aggregated.add(this.resource);
aggregated.setInterpolation(interpolation.toSis());
resourceCenter = r;
resourceBorder = aggregated;
}
}
}
}
use of org.geotoolkit.process.ProcessListener in project geotoolkit by Geomatys.
the class ProcessJob method execute.
@Override
public void execute(final JobExecutionContext jec) throws JobExecutionException {
final JobDataMap parameters = jec.getJobDetail().getJobDataMap();
final Object objFactoryId = parameters.get(KEY_FACTORY_ID);
final Object objProcessId = parameters.get(KEY_PROCESS_ID);
final Object objProcessParams = parameters.get(KEY_PARAMETERS);
final Object objProcess = parameters.get(KEY_PROCESS);
if (!(objFactoryId instanceof String)) {
throw new JobExecutionException("Factory id is not String, value found : " + objFactoryId);
}
if (!(objProcessId instanceof String)) {
throw new JobExecutionException("Process id is not String, value found : " + objProcessId);
}
if (!(objProcessParams instanceof ParameterValueGroup)) {
throw new JobExecutionException("Parameters is not an ISO parameter, value found : " + objProcessParams);
}
if (objProcess != null && !(objProcess instanceof Process)) {
throw new JobExecutionException("Process object is invalid, value found : " + objProcess);
}
final String factoryId = (String) objFactoryId;
final String processId = (String) objProcessId;
final Parameters params = Parameters.castOrWrap((ParameterValueGroup) objProcessParams);
process = (Process) objProcess;
if (process == null) {
final ProcessDescriptor desc = getProcessDescriptor(factoryId, processId);
process = desc.createProcess(params);
}
final StoreExceptionMonitor monitor = new StoreExceptionMonitor();
process.addListener(monitor);
for (ProcessListener pl : listeners) {
process.addListener(pl);
}
// set the result int he context, for listener that might want it.
final ParameterValueGroup result;
try {
result = process.call();
} catch (ProcessException ex) {
if (monitor.failed != null) {
throw monitor.failed;
} else {
throw new JobExecutionException(ex);
}
}
jec.setResult(result);
}
use of org.geotoolkit.process.ProcessListener in project geotoolkit by Geomatys.
the class ProcessJobDetail method getListeners.
public List<ProcessListener> getListeners() {
final List<ProcessListener> listeners = new ArrayList<>();
if (getJobDataMap().get(KEY_PROCESS) != null) {
final AbstractProcess process = (AbstractProcess) getJobDataMap().get(KEY_PROCESS);
Collections.addAll(listeners, process.getListeners());
}
return listeners;
}
use of org.geotoolkit.process.ProcessListener in project geotoolkit by Geomatys.
the class ForwardProcessListener method fireProgressing.
private void fireProgressing(String message, float progress, Exception ex) {
final ProcessEvent event = new ProcessEvent(parentProcess, message, progress, ex);
final ProcessListener[] listeners = parentProcess.getListeners();
for (ProcessListener listener : listeners) {
listener.progressing(event);
}
}
Aggregations