use of de.ii.ogcapi.foundation.domain.DefaultLinksGenerator in project ldproxy by interactive-instruments.
the class TilesQueriesHandlerImpl method getEmptyTileResponse.
private Response getEmptyTileResponse(QueryInputTileEmpty queryInput, ApiRequestContext requestContext) {
List<Link> links = new DefaultLinksGenerator().generateLinks(requestContext.getUriCustomizer(), requestContext.getMediaType(), requestContext.getAlternateMediaTypes(), i18n, requestContext.getLanguage());
Tile tile = queryInput.getTile();
if (!(tile.getOutputFormat() instanceof TileFormatWithQuerySupportExtension))
throw new RuntimeException(String.format("Unexpected tile format without query support. Found: %s", tile.getOutputFormat().getClass().getSimpleName()));
TileFormatWithQuerySupportExtension outputFormat = (TileFormatWithQuerySupportExtension) tile.getOutputFormat();
Date lastModified = null;
EntityTag etag = getEtag(tile.getOutputFormat().getEmptyTile(tile));
Response.ResponseBuilder response = evaluatePreconditions(requestContext, lastModified, etag);
if (Objects.nonNull(response))
return response.build();
return prepareSuccessResponse(requestContext, queryInput.getIncludeLinkHeader() ? links : null, lastModified, etag, queryInput.getCacheControl().orElse(null), queryInput.getExpires().orElse(null), null, true, String.format("%s_%d_%d_%d.%s", tile.getTileMatrixSet().getId(), tile.getTileLevel(), tile.getTileRow(), tile.getTileCol(), tile.getOutputFormat().getMediaType().fileExtension())).entity(tile.getOutputFormat().getEmptyTile(tile)).build();
}
use of de.ii.ogcapi.foundation.domain.DefaultLinksGenerator in project ldproxy by interactive-instruments.
the class TilesQueriesHandlerImpl method getMbtilesTileResponse.
private Response getMbtilesTileResponse(QueryInputTileMbtilesTile queryInput, ApiRequestContext requestContext) {
String mbtilesFilename = queryInput.getProvider().getFilename();
java.nio.file.Path provider = staticTileProviderStore.getTileProvider(queryInput.getTile().getApiData(), mbtilesFilename);
if (!provider.toFile().exists())
throw new RuntimeException(String.format("Mbtiles file '%s' does not exist", provider));
StreamingOutput streamingOutput = outputStream -> ByteStreams.copy(staticTileProviderStore.getTile(provider, queryInput.getTile()), outputStream);
List<Link> links = new DefaultLinksGenerator().generateLinks(requestContext.getUriCustomizer(), requestContext.getMediaType(), ImmutableList.of(), i18n, requestContext.getLanguage());
Date lastModified = getLastModified(provider.toFile());
EntityTag etag = getEtag(staticTileProviderStore.getTile(provider, queryInput.getTile()));
Response.ResponseBuilder response = evaluatePreconditions(requestContext, lastModified, etag);
if (Objects.nonNull(response))
return response.build();
Tile tile = queryInput.getTile();
return prepareSuccessResponse(requestContext, queryInput.getIncludeLinkHeader() ? links : null, lastModified, etag, queryInput.getCacheControl().orElse(null), queryInput.getExpires().orElse(null), null, true, String.format("%s_%d_%d_%d.%s", tile.getTileMatrixSet().getId(), tile.getTileLevel(), tile.getTileRow(), tile.getTileCol(), tile.getOutputFormat().getMediaType().fileExtension())).entity(streamingOutput).build();
}
use of de.ii.ogcapi.foundation.domain.DefaultLinksGenerator in project ldproxy by interactive-instruments.
the class TilesQueriesHandlerImpl method getTileStreamResponse.
private Response getTileStreamResponse(QueryInputTileStream queryInput, ApiRequestContext requestContext) {
byte[] content;
try {
content = queryInput.getTileContent().readAllBytes();
} catch (IOException e) {
throw new RuntimeException("Could not read tile from cache.", e);
}
StreamingOutput streamingOutput = outputStream -> ByteStreams.copy(new ByteArrayInputStream(content), outputStream);
List<Link> links = new DefaultLinksGenerator().generateLinks(requestContext.getUriCustomizer(), requestContext.getMediaType(), requestContext.getAlternateMediaTypes(), i18n, requestContext.getLanguage());
Date lastModified = queryInput.getLastModified().orElse(null);
EntityTag etag = getEtag(content);
Response.ResponseBuilder response = evaluatePreconditions(requestContext, lastModified, etag);
if (Objects.nonNull(response))
return response.build();
Tile tile = queryInput.getTile();
return prepareSuccessResponse(requestContext, queryInput.getIncludeLinkHeader() ? links : null, lastModified, etag, queryInput.getCacheControl().orElse(null), queryInput.getExpires().orElse(null), null, true, String.format("%s_%d_%d_%d.%s", tile.getTileMatrixSet().getId(), tile.getTileLevel(), tile.getTileRow(), tile.getTileCol(), tile.getOutputFormat().getMediaType().fileExtension())).entity(streamingOutput).build();
}
use of de.ii.ogcapi.foundation.domain.DefaultLinksGenerator in project ldproxy by interactive-instruments.
the class TilesQueriesHandlerImpl method getTileServerTileResponse.
private Response getTileServerTileResponse(QueryInputTileTileServerTile queryInput, ApiRequestContext requestContext) {
Tile tile = queryInput.getTile();
final String urlTemplate = tile.isDatasetTile() ? queryInput.getProvider().getUrlTemplate() : queryInput.getProvider().getUrlTemplateSingleCollection();
if (Objects.isNull(urlTemplate))
throw new IllegalStateException("The MAP_TILES configuration is invalid, no 'urlTemplate' was found.");
ApiMediaType mediaType = tile.getOutputFormat().getMediaType();
WebTarget client = ClientBuilder.newClient().target(urlTemplate).resolveTemplate("tileMatrix", tile.getTileLevel()).resolveTemplate("tileRow", tile.getTileRow()).resolveTemplate("tileCol", tile.getTileCol()).resolveTemplate("fileExtension", mediaType.fileExtension());
if (Objects.nonNull(tile.getCollectionId()))
client = client.resolveTemplate("collectionId", tile.getCollectionId());
Response response = client.request(mediaType.type()).get();
// unsuccessful? just forward the error response
if (response.getStatus() != 200)
return response;
List<Link> links = new DefaultLinksGenerator().generateLinks(requestContext.getUriCustomizer(), requestContext.getMediaType(), ImmutableList.of(), i18n, requestContext.getLanguage());
byte[] content;
try {
content = response.readEntity(InputStream.class).readAllBytes();
} catch (IOException e) {
throw new RuntimeException("Could not read map tile from TileServer.", e);
}
Date lastModified = null;
EntityTag etag = getEtag(content);
Response.ResponseBuilder responseBuilder = evaluatePreconditions(requestContext, lastModified, etag);
if (Objects.nonNull(responseBuilder))
return responseBuilder.build();
return prepareSuccessResponse(requestContext, queryInput.getIncludeLinkHeader() ? links : null, lastModified, etag, queryInput.getCacheControl().orElse(null), queryInput.getExpires().orElse(null), null, true, String.format("%s_%d_%d_%d.%s", tile.getTileMatrixSet().getId(), tile.getTileLevel(), tile.getTileRow(), tile.getTileCol(), tile.getOutputFormat().getMediaType().fileExtension())).entity(content).build();
}
use of de.ii.ogcapi.foundation.domain.DefaultLinksGenerator in project ldproxy by interactive-instruments.
the class TilesQueriesHandlerImpl method getMultiLayerTileResponse.
private Response getMultiLayerTileResponse(QueryInputTileMultiLayer queryInput, ApiRequestContext requestContext) {
OgcApi api = requestContext.getApi();
OgcApiDataV2 apiData = api.getData();
Tile multiLayerTile = queryInput.getTile();
List<String> collectionIds = multiLayerTile.getCollectionIds();
Map<String, FeatureQuery> queryMap = queryInput.getQueryMap();
Map<String, Tile> singleLayerTileMap = queryInput.getSingleLayerTileMap();
FeatureProvider2 featureProvider = multiLayerTile.getFeatureProvider().get();
TileMatrixSet tileMatrixSet = multiLayerTile.getTileMatrixSet();
int tileLevel = multiLayerTile.getTileLevel();
int tileRow = multiLayerTile.getTileRow();
int tileCol = multiLayerTile.getTileCol();
if (!(multiLayerTile.getOutputFormat() instanceof TileFormatWithQuerySupportExtension))
throw new RuntimeException(String.format("Unexpected tile format without query support. Found: %s", multiLayerTile.getOutputFormat().getClass().getSimpleName()));
TileFormatWithQuerySupportExtension outputFormat = (TileFormatWithQuerySupportExtension) multiLayerTile.getOutputFormat();
// process parameters and generate query
Optional<CrsTransformer> crsTransformer = Optional.empty();
EpsgCrs targetCrs = tileMatrixSet.getCrs();
if (featureProvider.supportsCrs()) {
EpsgCrs sourceCrs = featureProvider.crs().getNativeCrs();
crsTransformer = crsTransformerFactory.getTransformer(sourceCrs, targetCrs);
}
List<Link> links = new DefaultLinksGenerator().generateLinks(requestContext.getUriCustomizer(), requestContext.getMediaType(), requestContext.getAlternateMediaTypes(), i18n, requestContext.getLanguage());
Map<String, ByteArrayOutputStream> byteArrayMap = new HashMap<>();
for (String collectionId : collectionIds) {
// TODO limitation of the current model: all layers have to come from the same feature provider and use the same CRS
Tile tile = singleLayerTileMap.get(collectionId);
if (!multiLayerTile.getTemporary()) {
// use cached tile
try {
Optional<InputStream> tileContent = tileCache.getTile(tile);
if (tileContent.isPresent()) {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ByteStreams.copy(tileContent.get(), buffer);
byteArrayMap.put(collectionId, buffer);
continue;
}
} catch (SQLException | IOException e) {
// could not read the cache, generate the tile
}
}
String featureTypeId = apiData.getCollections().get(collectionId).getExtension(FeaturesCoreConfiguration.class).map(cfg -> cfg.getFeatureType().orElse(collectionId)).orElse(collectionId);
FeatureQuery query = queryMap.get(collectionId);
ImmutableFeatureTransformationContextTiles transformationContext;
try {
transformationContext = new ImmutableFeatureTransformationContextTiles.Builder().api(api).apiData(apiData).featureSchema(featureProvider.getData().getTypes().get(featureTypeId)).tile(tile).tileCache(tileCache).collectionId(collectionId).ogcApiRequest(requestContext).crsTransformer(crsTransformer).codelists(entityRegistry.getEntitiesForType(Codelist.class).stream().collect(Collectors.toMap(PersistentEntity::getId, c -> c))).defaultCrs(queryInput.getDefaultCrs()).links(links).isFeatureCollection(true).fields(query.getFields()).limit(query.getLimit()).offset(0).i18n(i18n).outputStream(new OutputStreamToByteConsumer()).build();
} catch (Exception e) {
throw new RuntimeException("Error building the tile transformation context.", e);
}
Optional<FeatureTokenEncoder<?>> encoder = outputFormat.getFeatureEncoder(transformationContext);
if (outputFormat.supportsFeatureQuery() && encoder.isPresent()) {
FeatureStream featureStream = featureProvider.queries().getFeatureStream(query);
ResultReduced<byte[]> result = generateTile(featureStream, encoder.get(), transformationContext, outputFormat);
if (result.isSuccess()) {
byte[] bytes = result.reduced();
ByteArrayOutputStream buffer = new ByteArrayOutputStream(bytes.length);
buffer.write(bytes, 0, bytes.length);
byteArrayMap.put(collectionId, buffer);
}
} else {
throw new NotAcceptableException(MessageFormat.format("The requested media type {0} cannot be generated, because it does not support streaming.", requestContext.getMediaType().type()));
}
}
TileFormatWithQuerySupportExtension.MultiLayerTileContent result;
try {
result = outputFormat.combineSingleLayerTilesToMultiLayerTile(tileMatrixSet, singleLayerTileMap, byteArrayMap);
} catch (IOException e) {
throw new RuntimeException("Error accessing the tile cache.", e);
}
// try to write/update tile in cache, if all collections have been processed
if (result.isComplete) {
try {
tileCache.storeTile(multiLayerTile, result.byteArray);
} catch (Throwable e) {
String msg = "Failure to write the multi-layer file of tile {}/{}/{}/{} in dataset '{}', format '{}' to the cache";
LogContext.errorAsInfo(LOGGER, e, msg, tileMatrixSet.getId(), tileLevel, tileRow, tileCol, api.getId(), outputFormat.getExtension());
}
}
Date lastModified = null;
EntityTag etag = getEtag(result.byteArray);
Response.ResponseBuilder response = evaluatePreconditions(requestContext, lastModified, etag);
if (Objects.nonNull(response))
return response.build();
return prepareSuccessResponse(requestContext, queryInput.getIncludeLinkHeader() ? links : null, lastModified, etag, queryInput.getCacheControl().orElse(null), queryInput.getExpires().orElse(null), null, true, String.format("%s_%d_%d_%d.%s", tileMatrixSet.getId(), tileLevel, tileRow, tileCol, outputFormat.getMediaType().fileExtension())).entity(result.byteArray).build();
}
Aggregations