Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
*/
package de.ii.xtraplatform.tiles.app;

import de.ii.xtraplatform.crs.domain.BoundingBox;
import de.ii.xtraplatform.crs.domain.CrsTransformationException;
import de.ii.xtraplatform.crs.domain.CrsTransformerFactory;
import de.ii.xtraplatform.crs.domain.OgcCrs;
import de.ii.xtraplatform.tiles.domain.ChainedTileProvider;
import de.ii.xtraplatform.tiles.domain.ImmutableTileQuery;
import de.ii.xtraplatform.tiles.domain.TileEncoder;
Expand All @@ -21,6 +25,7 @@
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import no.ecc.vectortile.VectorTileDecoder;
Expand All @@ -32,7 +37,15 @@ public class TileEncoderMvt implements TileEncoder {

private static final Logger LOGGER = LoggerFactory.getLogger(TileEncoderMvt.class);

public TileEncoderMvt() {}
private final Function<String, Optional<BoundingBox>> tilesetBounds;
private final CrsTransformerFactory crsTransformerFactory;

public TileEncoderMvt(
Function<String, Optional<BoundingBox>> tilesetBounds,
CrsTransformerFactory crsTransformerFactory) {
this.tilesetBounds = tilesetBounds;
this.crsTransformerFactory = crsTransformerFactory;
}

@Override
public byte[] empty(TileMatrixSetBase tms) {
Expand All @@ -48,8 +61,15 @@ public byte[] combine(
getLayerTilesets(data, combinedTileset, tile.getGenerationParametersTransient());
VectorTileEncoder encoder = new VectorTileEncoder(tile.getTileMatrixSet().getTileExtent());
VectorTileDecoder decoder = new VectorTileDecoder();
Optional<BoundingBox> tileBounds = getTileBounds(tile);

for (String tileset : tilesets) {
// a tileset without data in the area of the tile cannot contribute a layer; without this
// check, a tile that is not in the cache, because it was not seeded, would be generated
if (isOutsideBounds(tileset, tileBounds)) {
continue;
}

TileQuery tileQuery = ImmutableTileQuery.builder().from(tile).tileset(tileset).build();
TileResult layer = tileProvider.get(tileQuery);

Expand Down Expand Up @@ -90,6 +110,26 @@ public byte[] combine(
return encoder.encode();
}

private Optional<BoundingBox> getTileBounds(TileQuery tile) {
try {
return Optional.of(tile.getBoundingBox(OgcCrs.CRS84, crsTransformerFactory));
} catch (CrsTransformationException e) {
// ignore, assume that all tilesets may have data
return Optional.empty();
}
}

private boolean isOutsideBounds(String tileset, Optional<BoundingBox> tileBounds) {
if (tileBounds.isEmpty()) {
return false;
}

return tilesetBounds
.apply(tileset)
.filter(bounds -> !BoundingBox.intersects(bounds, tileBounds.get()))
.isPresent();
}

private List<String> getLayerTilesets(
TileProviderFeaturesData data,
TilesetFeatures combinedTileset,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Range;
import de.ii.xtraplatform.crs.domain.BoundingBox;
import de.ii.xtraplatform.crs.domain.CrsTransformerFactory;
import de.ii.xtraplatform.tiles.domain.ChainedTileProvider;
import de.ii.xtraplatform.tiles.domain.TileEncoder;
import de.ii.xtraplatform.tiles.domain.TileMatrixSetBase;
Expand All @@ -18,16 +20,24 @@
import jakarta.ws.rs.core.MediaType;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

public class TileEncoders implements ChainedTileProvider {
private static final Map<MediaType, TileEncoder> ENCODERS =
ImmutableMap.of(FeatureEncoderMVT.FORMAT, new TileEncoderMvt());
private final Map<MediaType, TileEncoder> encoders;
private final TileProviderFeaturesData data;
private final ChainedTileProvider generatorProviderChain;

public TileEncoders(TileProviderFeaturesData data, ChainedTileProvider generatorProviderChain) {
public TileEncoders(
TileProviderFeaturesData data,
ChainedTileProvider generatorProviderChain,
Function<String, Optional<BoundingBox>> tilesetBounds,
CrsTransformerFactory crsTransformerFactory) {
this.data = data;
this.generatorProviderChain = generatorProviderChain;
this.encoders =
ImmutableMap.of(
FeatureEncoderMVT.FORMAT, new TileEncoderMvt(tilesetBounds, crsTransformerFactory));
}

@Override
Expand All @@ -48,14 +58,14 @@ public TileResult getTile(TileQuery tile) throws IOException {
}

public boolean canEncode(MediaType mediaType) {
return ENCODERS.containsKey(mediaType);
return encoders.containsKey(mediaType);
}

public byte[] empty(MediaType mediaType, TileMatrixSetBase tms) {
return ENCODERS.get(mediaType).empty(tms);
return encoders.get(mediaType).empty(tms);
}

public byte[] combine(TileQuery tile) throws IOException {
return ENCODERS.get(tile.getMediaType()).combine(tile, data, generatorProviderChain);
return encoders.get(tile.getMediaType()).combine(tile, data, generatorProviderChain);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public class TileProviderFeatures extends AbstractTileProvider<TileProviderFeatu
static final String TILES_DIR_NAME = "tiles";

private final TileGenerator tileGenerator;
private final CrsTransformerFactory crsTransformerFactory;
private final Map<Type, Map<Storage, TileStore>> tileStores;
private final List<TileCache> generatorCaches;
private final List<TileCache> combinerCaches;
Expand Down Expand Up @@ -149,6 +150,7 @@ public TileProviderFeatures(
this.asyncStartup = appContext.getConfiguration().getModules().isStartupAsync();
this.tileMatrixSetRepository = Optional.of(tileMatrixSetRepository);
this.dataDir = appContext.getDataDir().toString();
this.crsTransformerFactory = crsTransformerFactory;
this.tileGenerator =
new TileGeneratorFeatures(
data,
Expand Down Expand Up @@ -226,7 +228,9 @@ private void init() {

this.generatorProviderChain = current;

this.tileEncoders = new TileEncoders(getData(), generatorProviderChain);
this.tileEncoders =
new TileEncoders(
getData(), generatorProviderChain, this::getTilesetBounds, crsTransformerFactory);
current = tileEncoders;

for (int i = 0; i < getData().getCaches().size(); i++) {
Expand Down Expand Up @@ -547,6 +551,14 @@ public Optional<TilesetMetadata> getMetadata(String tilesetId) {
return Optional.ofNullable(metadata.get(tilesetId));
}

/**
* The area in which the tileset may have data, that is the spatial extent of the feature types of
* its layers. Empty, if the extent is unknown.
*/
private Optional<BoundingBox> getTilesetBounds(String tileset) {
return getMetadata(tileset).flatMap(TilesetMetadata::getBounds);
}

@Override
public Optional<TilesetMetadata> getMetadata(String vectorTilesetId, String mapStyleId) {
return Optional.ofNullable(metadata.get(getMapStyleTileset(vectorTilesetId, mapStyleId)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ public JobResult process(Job job, JobSet jobSet, JobQueueMin jobQueue) {
});
}

// when no tileset of the job set has tiles to seed, no job was added and the total is still
// unknown; a total of zero makes the job set complete instead of leaving it in the queue,
// where it would never reach 100% and suppress every following seeding run
jobSet.getTotal().compareAndSet(-1, 0);

if (jobSet.isDone()) {
jobSet.getCleanup().ifPresent(jobQueue::push);
return JobResult.success(); // early return
Expand Down
Loading