Search in sources :

Example 1 with PropertyTransformations

use of de.ii.xtraplatform.features.domain.transform.PropertyTransformations in project ldproxy by interactive-instruments.

the class SchemaCacheFlatgeobuf method deriveSchema.

@Override
protected FeatureSchema deriveSchema(FeatureSchema schema, OgcApiDataV2 apiData, FeatureTypeConfigurationOgcApi collectionData) {
    Optional<PropertyTransformations> propertyTransformations = collectionData.getExtension(FlatgeobufConfiguration.class).map(configuration -> (PropertyTransformations) configuration);
    WithTransformationsApplied schemaTransformer = propertyTransformations.map(WithTransformationsApplied::new).orElse(new WithTransformationsApplied());
    Optional<String> separator = schemaTransformer.getFlatteningSeparator(schema);
    if (separator.isEmpty())
        return schema.accept(schemaTransformer);
    int maxMultiplicity = collectionData.getExtension(FlatgeobufConfiguration.class).map(FlatgeobufConfiguration::getMaxMultiplicity).orElse(DEFAULT_MULTIPLICITY);
    FanOutArrays arrayTransformer = new FanOutArrays(separator.get(), maxMultiplicity);
    return schema.accept(schemaTransformer).accept(arrayTransformer).get(0);
}
Also used : PropertyTransformations(de.ii.xtraplatform.features.domain.transform.PropertyTransformations) WithTransformationsApplied(de.ii.xtraplatform.features.domain.transform.WithTransformationsApplied) FlatgeobufConfiguration(de.ii.ogcapi.features.flatgeobuf.domain.FlatgeobufConfiguration) FanOutArrays(de.ii.ogcapi.features.core.domain.FanOutArrays)

Example 2 with PropertyTransformations

use of de.ii.xtraplatform.features.domain.transform.PropertyTransformations in project ldproxy by interactive-instruments.

the class SchemaCacheReturnables method deriveSchema.

@Override
protected JsonSchemaDocument deriveSchema(FeatureSchema schema, OgcApiDataV2 apiData, FeatureTypeConfigurationOgcApi collectionData, Optional<String> schemaUri, VERSION version) {
    Optional<PropertyTransformations> propertyTransformations = collectionData.getExtension(GeoJsonConfiguration.class).map(geoJsonConfiguration -> (PropertyTransformations) geoJsonConfiguration);
    WithTransformationsApplied schemaTransformer = propertyTransformations.map(WithTransformationsApplied::new).orElse(new WithTransformationsApplied());
    SchemaDeriverReturnables schemaDeriverReturnables = new SchemaDeriverReturnables(version, schemaUri, collectionData.getLabel(), Optional.empty(), codelistSupplier.get());
    return (JsonSchemaDocument) schema.accept(schemaTransformer).accept(schemaDeriverReturnables);
}
Also used : JsonSchemaDocument(de.ii.ogcapi.features.core.domain.JsonSchemaDocument) GeoJsonConfiguration(de.ii.ogcapi.features.geojson.domain.GeoJsonConfiguration) PropertyTransformations(de.ii.xtraplatform.features.domain.transform.PropertyTransformations) SchemaDeriverReturnables(de.ii.ogcapi.features.geojson.domain.SchemaDeriverReturnables) WithTransformationsApplied(de.ii.xtraplatform.features.domain.transform.WithTransformationsApplied)

Example 3 with PropertyTransformations

use of de.ii.xtraplatform.features.domain.transform.PropertyTransformations in project ldproxy by interactive-instruments.

the class TilesQueriesHandlerImpl method generateTile.

private ResultReduced<byte[]> generateTile(FeatureStream featureStream, FeatureTokenEncoder<?> encoder, FeatureTransformationContextTiles transformationContext, TileFormatWithQuerySupportExtension outputFormat) {
    Optional<PropertyTransformations> propertyTransformations = transformationContext.getCollection().flatMap(collection -> outputFormat.getPropertyTransformations(collection, ImmutableMap.of("serviceUrl", transformationContext.getServiceUrl()), outputFormat.getBuildingBlockConfigurationType()));
    SinkReduced<Object, byte[]> featureSink = encoder.to(Sink.reduceByteArray());
    try {
        ResultReduced<byte[]> result = featureStream.runWith(featureSink, propertyTransformations).toCompletableFuture().join();
        if (result.isSuccess()) {
            Tile tile = transformationContext.tile();
            try {
                // write/update tile in cache
                tileCache.storeTile(tile, result.reduced());
            } 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, tile.getTileMatrixSet().getId(), tile.getTileLevel(), tile.getTileRow(), tile.getTileCol(), transformationContext.getApiData().getId(), outputFormat.getExtension());
            }
        } else {
            result.getError().ifPresent(QueriesHandler::processStreamError);
        }
        return result;
    } catch (CompletionException e) {
        if (e.getCause() instanceof WebApplicationException) {
            throw (WebApplicationException) e.getCause();
        }
        throw new IllegalStateException("Feature stream error.", e.getCause());
    }
}
Also used : TilesQueriesHandler(de.ii.ogcapi.tiles.domain.TilesQueriesHandler) QueriesHandler(de.ii.ogcapi.foundation.domain.QueriesHandler) PropertyTransformations(de.ii.xtraplatform.features.domain.transform.PropertyTransformations) WebApplicationException(javax.ws.rs.WebApplicationException) CompletionException(java.util.concurrent.CompletionException) Tile(de.ii.ogcapi.tiles.domain.Tile)

Example 4 with PropertyTransformations

use of de.ii.xtraplatform.features.domain.transform.PropertyTransformations in project ldproxy by interactive-instruments.

the class FeaturesCoreQueriesHandlerImpl method getItemsResponse.

private Response getItemsResponse(OgcApi api, ApiRequestContext requestContext, String collectionId, String featureId, QueryInput queryInput, FeatureQuery query, FeatureProvider2 featureProvider, String canonicalUri, FeatureFormatExtension outputFormat, boolean onlyHitsIfMore, Optional<Integer> defaultPageSize, boolean showsFeatureSelfLink, boolean includeLinkHeader, EpsgCrs defaultCrs) {
    ensureCollectionIdExists(api.getData(), collectionId);
    ensureFeatureProviderSupportsQueries(featureProvider);
    Optional<CrsTransformer> crsTransformer = Optional.empty();
    EpsgCrs sourceCrs = null;
    EpsgCrs targetCrs = query.getCrs().orElse(defaultCrs);
    if (featureProvider.supportsCrs()) {
        sourceCrs = featureProvider.crs().getNativeCrs();
        crsTransformer = crsTransformerFactory.getTransformer(sourceCrs, targetCrs);
    }
    List<ApiMediaType> alternateMediaTypes = requestContext.getAlternateMediaTypes();
    List<Link> links = Objects.isNull(featureId) ? new FeaturesLinksGenerator().generateLinks(requestContext.getUriCustomizer(), query.getOffset(), query.getLimit(), defaultPageSize.orElse(0), requestContext.getMediaType(), alternateMediaTypes, i18n, requestContext.getLanguage()) : new FeatureLinksGenerator().generateLinks(requestContext.getUriCustomizer(), requestContext.getMediaType(), alternateMediaTypes, outputFormat.getCollectionMediaType(), canonicalUri, i18n, requestContext.getLanguage());
    String featureTypeId = api.getData().getCollections().get(collectionId).getExtension(FeaturesCoreConfiguration.class).map(cfg -> cfg.getFeatureType().orElse(collectionId)).orElse(collectionId);
    ImmutableFeatureTransformationContextGeneric.Builder transformationContext = new ImmutableFeatureTransformationContextGeneric.Builder().api(api).apiData(api.getData()).featureSchema(featureProvider.getData().getTypes().get(featureTypeId)).collectionId(collectionId).ogcApiRequest(requestContext).crsTransformer(crsTransformer).codelists(entityRegistry.getEntitiesForType(Codelist.class).stream().collect(Collectors.toMap(PersistentEntity::getId, c -> c))).defaultCrs(defaultCrs).sourceCrs(Optional.ofNullable(sourceCrs)).links(links).isFeatureCollection(Objects.isNull(featureId)).isHitsOnly(query.hitsOnly()).isPropertyOnly(query.propertyOnly()).fields(query.getFields()).limit(query.getLimit()).offset(query.getOffset()).maxAllowableOffset(query.getMaxAllowableOffset()).geometryPrecision(query.getGeometryPrecision()).isHitsOnlyIfMore(onlyHitsIfMore).showsFeatureSelfLink(showsFeatureSelfLink);
    StreamingOutput streamingOutput;
    if (outputFormat.canPassThroughFeatures() && featureProvider.supportsPassThrough() && outputFormat.getMediaType().matches(featureProvider.passThrough().getMediaType())) {
        FeatureStream featureStream = featureProvider.passThrough().getFeatureStreamPassThrough(query);
        ImmutableFeatureTransformationContextGeneric transformationContextGeneric = transformationContext.outputStream(new OutputStreamToByteConsumer()).build();
        FeatureTokenEncoder<?> encoder = outputFormat.getFeatureEncoderPassThrough(transformationContextGeneric, requestContext.getLanguage()).get();
        streamingOutput = stream(featureStream, Objects.nonNull(featureId), encoder, Optional.empty());
    } else if (outputFormat.canEncodeFeatures()) {
        FeatureStream featureStream = featureProvider.queries().getFeatureStream(query);
        ImmutableFeatureTransformationContextGeneric transformationContextGeneric = transformationContext.outputStream(new OutputStreamToByteConsumer()).build();
        FeatureTokenEncoder<?> encoder = outputFormat.getFeatureEncoder(transformationContextGeneric, requestContext.getLanguage()).get();
        Optional<PropertyTransformations> propertyTransformations = outputFormat.getPropertyTransformations(api.getData().getCollections().get(collectionId)).map(pt -> pt.withSubstitutions(ImmutableMap.of("serviceUrl", transformationContextGeneric.getServiceUrl())));
        streamingOutput = stream(featureStream, Objects.nonNull(featureId), encoder, propertyTransformations);
    } else {
        throw new NotAcceptableException(MessageFormat.format("The requested media type {0} cannot be generated, because it does not support streaming.", requestContext.getMediaType().type()));
    }
    Date lastModified = null;
    EntityTag etag = null;
    byte[] result = null;
    if (Objects.nonNull(featureId)) {
        // support etag from the content for a single feature
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            streamingOutput.write(baos);
        } catch (IOException e) {
            throw new IllegalStateException("Feature stream error.", e);
        }
        result = baos.toByteArray();
        etag = !outputFormat.getMediaType().type().equals(MediaType.TEXT_HTML_TYPE) || api.getData().getExtension(HtmlConfiguration.class, collectionId).map(HtmlConfiguration::getSendEtags).orElse(false) ? getEtag(result) : null;
    } else {
        lastModified = getLastModified(queryInput, requestContext.getApi(), featureProvider);
    }
    Response.ResponseBuilder response = evaluatePreconditions(requestContext, lastModified, etag);
    if (Objects.nonNull(response))
        return response.build();
    return prepareSuccessResponse(requestContext, includeLinkHeader ? links.stream().filter(link -> !"next".equalsIgnoreCase(link.getRel())).collect(ImmutableList.toImmutableList()) : null, lastModified, etag, queryInput.getCacheControl().orElse(null), queryInput.getExpires().orElse(null), targetCrs, true, String.format("%s.%s", Objects.isNull(featureId) ? collectionId : featureId, outputFormat.getMediaType().fileExtension())).entity(Objects.nonNull(result) ? result : streamingOutput).build();
}
Also used : Date(java.util.Date) Link(de.ii.ogcapi.foundation.domain.Link) LoggerFactory(org.slf4j.LoggerFactory) EpsgCrs(de.ii.xtraplatform.crs.domain.EpsgCrs) ApiMediaType(de.ii.ogcapi.foundation.domain.ApiMediaType) MediaType(javax.ws.rs.core.MediaType) Map(java.util.Map) OutputStreamToByteConsumer(de.ii.xtraplatform.streams.domain.OutputStreamToByteConsumer) PersistentEntity(de.ii.xtraplatform.store.domain.entities.PersistentEntity) HtmlConfiguration(de.ii.ogcapi.html.domain.HtmlConfiguration) ApiRequestContext(de.ii.ogcapi.foundation.domain.ApiRequestContext) ImmutableMap(com.google.common.collect.ImmutableMap) FeatureTokenEncoder(de.ii.xtraplatform.features.domain.FeatureTokenEncoder) OgcApi(de.ii.ogcapi.foundation.domain.OgcApi) Codelist(de.ii.xtraplatform.codelists.domain.Codelist) CompletionException(java.util.concurrent.CompletionException) StreamingOutput(javax.ws.rs.core.StreamingOutput) Collectors(java.util.stream.Collectors) NotFoundException(javax.ws.rs.NotFoundException) Objects(java.util.Objects) List(java.util.List) StringTemplateFilters(de.ii.xtraplatform.strings.domain.StringTemplateFilters) Response(javax.ws.rs.core.Response) OgcApiDataV2(de.ii.ogcapi.foundation.domain.OgcApiDataV2) CrsTransformerFactory(de.ii.xtraplatform.crs.domain.CrsTransformerFactory) ResultOld(de.ii.xtraplatform.features.domain.FeatureStream2.ResultOld) Sink(de.ii.xtraplatform.streams.domain.Reactive.Sink) Optional(java.util.Optional) WebApplicationException(javax.ws.rs.WebApplicationException) EntityRegistry(de.ii.xtraplatform.store.domain.entities.EntityRegistry) QueryHandler(de.ii.ogcapi.foundation.domain.QueryHandler) FeatureQuery(de.ii.xtraplatform.features.domain.FeatureQuery) ByteArrayOutputStream(java.io.ByteArrayOutputStream) CrsTransformer(de.ii.xtraplatform.crs.domain.CrsTransformer) QueryInput(de.ii.ogcapi.foundation.domain.QueryInput) PropertyTransformations(de.ii.xtraplatform.features.domain.transform.PropertyTransformations) Singleton(javax.inject.Singleton) SinkTransformed(de.ii.xtraplatform.streams.domain.Reactive.SinkTransformed) Function(java.util.function.Function) AutoBind(com.github.azahnen.dagger.annotations.AutoBind) MessageFormat(java.text.MessageFormat) FeatureConsumer(de.ii.xtraplatform.features.domain.FeatureConsumer) Inject(javax.inject.Inject) ImmutableList(com.google.common.collect.ImmutableList) QueriesHandler(de.ii.ogcapi.foundation.domain.QueriesHandler) Result(de.ii.xtraplatform.features.domain.FeatureStream.Result) OutputStream(java.io.OutputStream) NotAcceptableException(javax.ws.rs.NotAcceptableException) Logger(org.slf4j.Logger) FeatureFormatExtension(de.ii.ogcapi.features.core.domain.FeatureFormatExtension) I18n(de.ii.ogcapi.foundation.domain.I18n) IOException(java.io.IOException) FeatureStream(de.ii.xtraplatform.features.domain.FeatureStream) EntityTag(javax.ws.rs.core.EntityTag) FeatureProvider2(de.ii.xtraplatform.features.domain.FeatureProvider2) FeaturesCoreConfiguration(de.ii.ogcapi.features.core.domain.FeaturesCoreConfiguration) FeaturesCoreQueriesHandler(de.ii.ogcapi.features.core.domain.FeaturesCoreQueriesHandler) FeatureLinksGenerator(de.ii.ogcapi.features.core.domain.FeatureLinksGenerator) FeatureSourceStream(de.ii.xtraplatform.features.domain.FeatureSourceStream) FeaturesLinksGenerator(de.ii.ogcapi.features.core.domain.FeaturesLinksGenerator) ImmutableFeatureTransformationContextGeneric(de.ii.ogcapi.features.core.domain.ImmutableFeatureTransformationContextGeneric) FeatureStream(de.ii.xtraplatform.features.domain.FeatureStream) HtmlConfiguration(de.ii.ogcapi.html.domain.HtmlConfiguration) StreamingOutput(javax.ws.rs.core.StreamingOutput) OutputStreamToByteConsumer(de.ii.xtraplatform.streams.domain.OutputStreamToByteConsumer) CrsTransformer(de.ii.xtraplatform.crs.domain.CrsTransformer) FeatureLinksGenerator(de.ii.ogcapi.features.core.domain.FeatureLinksGenerator) EntityTag(javax.ws.rs.core.EntityTag) Optional(java.util.Optional) ApiMediaType(de.ii.ogcapi.foundation.domain.ApiMediaType) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) Date(java.util.Date) ImmutableFeatureTransformationContextGeneric(de.ii.ogcapi.features.core.domain.ImmutableFeatureTransformationContextGeneric) Response(javax.ws.rs.core.Response) FeatureTokenEncoder(de.ii.xtraplatform.features.domain.FeatureTokenEncoder) EpsgCrs(de.ii.xtraplatform.crs.domain.EpsgCrs) NotAcceptableException(javax.ws.rs.NotAcceptableException) FeaturesLinksGenerator(de.ii.ogcapi.features.core.domain.FeaturesLinksGenerator) Link(de.ii.ogcapi.foundation.domain.Link)

Aggregations

PropertyTransformations (de.ii.xtraplatform.features.domain.transform.PropertyTransformations)4 QueriesHandler (de.ii.ogcapi.foundation.domain.QueriesHandler)2 WithTransformationsApplied (de.ii.xtraplatform.features.domain.transform.WithTransformationsApplied)2 CompletionException (java.util.concurrent.CompletionException)2 WebApplicationException (javax.ws.rs.WebApplicationException)2 AutoBind (com.github.azahnen.dagger.annotations.AutoBind)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 FanOutArrays (de.ii.ogcapi.features.core.domain.FanOutArrays)1 FeatureFormatExtension (de.ii.ogcapi.features.core.domain.FeatureFormatExtension)1 FeatureLinksGenerator (de.ii.ogcapi.features.core.domain.FeatureLinksGenerator)1 FeaturesCoreConfiguration (de.ii.ogcapi.features.core.domain.FeaturesCoreConfiguration)1 FeaturesCoreQueriesHandler (de.ii.ogcapi.features.core.domain.FeaturesCoreQueriesHandler)1 FeaturesLinksGenerator (de.ii.ogcapi.features.core.domain.FeaturesLinksGenerator)1 ImmutableFeatureTransformationContextGeneric (de.ii.ogcapi.features.core.domain.ImmutableFeatureTransformationContextGeneric)1 JsonSchemaDocument (de.ii.ogcapi.features.core.domain.JsonSchemaDocument)1 FlatgeobufConfiguration (de.ii.ogcapi.features.flatgeobuf.domain.FlatgeobufConfiguration)1 GeoJsonConfiguration (de.ii.ogcapi.features.geojson.domain.GeoJsonConfiguration)1 SchemaDeriverReturnables (de.ii.ogcapi.features.geojson.domain.SchemaDeriverReturnables)1 ApiMediaType (de.ii.ogcapi.foundation.domain.ApiMediaType)1