use of de.ii.ogcapi.features.core.domain.FeaturesCoreConfiguration in project ldproxy by interactive-instruments.
the class TileProviderFeatures method getQueryInput.
@Override
@JsonIgnore
@Value.Derived
public QueryInput getQueryInput(OgcApiDataV2 apiData, URICustomizer uriCustomizer, Map<String, String> queryParameters, List<OgcApiQueryParameter> allowedParameters, QueryInput genericInput, Tile tile) {
if (!tile.getFeatureProvider().map(FeatureProvider2::supportsQueries).orElse(false)) {
throw new IllegalStateException("Tile cannot be generated. The feature provider does not support feature queries.");
}
TileFormatExtension outputFormat = tile.getOutputFormat();
List<String> collections = tile.getCollectionIds();
if (collections.isEmpty()) {
return new ImmutableQueryInputTileEmpty.Builder().from(genericInput).tile(tile).build();
}
if (!(outputFormat instanceof TileFormatWithQuerySupportExtension))
throw new RuntimeException(String.format("Unexpected tile format without query support. Found: %s", outputFormat.getClass().getSimpleName()));
// first execute the information that is passed as processing parameters (e.g., "properties")
Map<String, Object> processingParameters = new HashMap<>();
for (OgcApiQueryParameter parameter : allowedParameters) {
processingParameters = parameter.transformContext(null, processingParameters, queryParameters, apiData);
}
if (tile.isDatasetTile()) {
if (!outputFormat.canMultiLayer() && collections.size() > 1)
throw new NotAcceptableException("The requested tile format supports only a single layer. Please select only a single collection.");
Map<String, Tile> singleLayerTileMap = collections.stream().collect(ImmutableMap.toImmutableMap(collectionId -> collectionId, collectionId -> new ImmutableTile.Builder().from(tile).collectionIds(ImmutableList.of(collectionId)).isDatasetTile(false).build()));
Map<String, FeatureQuery> queryMap = collections.stream().filter(collectionId -> {
Optional<FeaturesCoreConfiguration> featuresConfiguration = apiData.getCollections().get(collectionId).getExtension(FeaturesCoreConfiguration.class);
return featuresConfiguration.isPresent() && featuresConfiguration.get().getQueryables().isPresent() && !featuresConfiguration.get().getQueryables().get().getSpatial().isEmpty();
}).collect(ImmutableMap.toImmutableMap(collectionId -> collectionId, collectionId -> {
String featureTypeId = apiData.getCollections().get(collectionId).getExtension(FeaturesCoreConfiguration.class).map(cfg -> cfg.getFeatureType().orElse(collectionId)).orElse(collectionId);
TilesConfiguration layerConfiguration = apiData.getExtension(TilesConfiguration.class, collectionId).orElseThrow();
FeatureQuery query = ((TileFormatWithQuerySupportExtension) outputFormat).getQuery(singleLayerTileMap.get(collectionId), allowedParameters, queryParameters, layerConfiguration, uriCustomizer);
return ImmutableFeatureQuery.builder().from(query).type(featureTypeId).build();
}));
FeaturesCoreConfiguration coreConfiguration = apiData.getExtension(FeaturesCoreConfiguration.class).orElseThrow();
return new ImmutableQueryInputTileMultiLayer.Builder().from(genericInput).tile(tile).singleLayerTileMap(singleLayerTileMap).queryMap(queryMap).processingParameters(processingParameters).defaultCrs(apiData.getExtension(FeaturesCoreConfiguration.class).map(FeaturesCoreConfiguration::getDefaultEpsgCrs).orElseThrow()).build();
} else {
String collectionId = tile.getCollectionId();
FeatureTypeConfigurationOgcApi featureType = apiData.getCollectionData(collectionId).orElseThrow();
TilesConfiguration layerConfiguration = apiData.getExtension(TilesConfiguration.class, collectionId).orElseThrow();
FeatureQuery query = ((TileFromFeatureQuery) outputFormat).getQuery(tile, allowedParameters, queryParameters, layerConfiguration, uriCustomizer);
FeaturesCoreConfiguration coreConfiguration = featureType.getExtension(FeaturesCoreConfiguration.class).orElseThrow();
return new ImmutableQueryInputTileSingleLayer.Builder().from(genericInput).tile(tile).query(query).processingParameters(processingParameters).defaultCrs(featureType.getExtension(FeaturesCoreConfiguration.class).map(FeaturesCoreConfiguration::getDefaultEpsgCrs).orElseThrow()).build();
}
}
use of de.ii.ogcapi.features.core.domain.FeaturesCoreConfiguration in project ldproxy by interactive-instruments.
the class FeaturesFormatHtml method getFeatureEncoder.
@Override
public Optional<FeatureTokenEncoder<?>> getFeatureEncoder(FeatureTransformationContext transformationContext, Optional<Locale> language) {
OgcApi api = transformationContext.getApi();
OgcApiDataV2 apiData = transformationContext.getApiData();
String collectionName = transformationContext.getCollectionId();
String staticUrlPrefix = transformationContext.getOgcApiRequest().getStaticUrlPrefix();
URICustomizer uriCustomizer = transformationContext.getOgcApiRequest().getUriCustomizer();
FeatureCollectionView featureTypeDataset;
boolean bare = transformationContext.getOgcApiRequest().getUriCustomizer().getQueryParams().stream().anyMatch(nameValuePair -> nameValuePair.getName().equals("bare") && nameValuePair.getValue().equals("true"));
if (transformationContext.isFeatureCollection()) {
FeatureTypeConfigurationOgcApi collectionData = apiData.getCollections().get(collectionName);
Integer htmlMaxLimit = collectionData.getExtension(FeaturesHtmlConfiguration.class).map(FeaturesHtmlConfiguration::getMaximumPageSize).orElse(null);
if (Objects.nonNull(htmlMaxLimit) && htmlMaxLimit < transformationContext.getLimit())
throw new IllegalArgumentException(String.format("The HTML output has a maximum page size (parameter 'limit') of %d. Found: %d", htmlMaxLimit, transformationContext.getLimit()));
Optional<FeaturesCoreConfiguration> featuresCoreConfiguration = collectionData.getExtension(FeaturesCoreConfiguration.class);
List<String> queryables = featuresCoreConfiguration.map(FeaturesCoreConfiguration::getQOrOtherFilterParameters).orElse(ImmutableList.of());
Map<String, String> filterableFields = transformationContext.getFeatureSchema().map(schema -> schema.accept(SCHEMA_FLATTENER)).map(schema -> schema.getProperties().stream().filter(property -> queryables.contains(property.getName())).map(property -> new SimpleImmutableEntry<>(property.getName(), property.getLabel().orElse(property.getName()))).collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue))).orElse(ImmutableMap.of());
featureTypeDataset = createFeatureCollectionView(api, apiData.getCollections().get(collectionName), uriCustomizer.copy(), filterableFields, staticUrlPrefix, bare, language, isNoIndexEnabledForApi(apiData), getMapPosition(apiData, collectionName), getGeometryProperties(apiData, collectionName));
addDatasetNavigation(featureTypeDataset, apiData.getLabel(), apiData.getCollections().get(collectionName).getLabel(), transformationContext.getLinks(), uriCustomizer.copy(), language, apiData.getSubPath());
} else {
featureTypeDataset = createFeatureDetailsView(api, apiData.getCollections().get(collectionName), uriCustomizer.copy(), transformationContext.getLinks(), apiData.getLabel(), uriCustomizer.getLastPathSegment(), staticUrlPrefix, language, isNoIndexEnabledForApi(apiData), apiData.getSubPath(), getMapPosition(apiData, collectionName), getGeometryProperties(apiData, collectionName));
}
ImmutableFeatureTransformationContextHtml transformationContextHtml = ImmutableFeatureTransformationContextHtml.builder().from(transformationContext).collectionView(featureTypeDataset).codelists(entityRegistry.getEntitiesForType(Codelist.class).stream().collect(Collectors.toMap(c -> c.getId(), c -> c))).mustacheRenderer(mustacheRenderer).i18n(i18n).language(language).build();
return Optional.of(new FeatureEncoderHtml(transformationContextHtml));
}
use of de.ii.ogcapi.features.core.domain.FeaturesCoreConfiguration in project ldproxy by interactive-instruments.
the class EndpointFeatures method getItems.
@GET
@Path("/{collectionId}/items")
public Response getItems(@Auth Optional<User> optionalUser, @Context OgcApi api, @Context ApiRequestContext requestContext, @Context UriInfo uriInfo, @PathParam("collectionId") String collectionId) {
checkCollectionExists(api.getData(), collectionId);
FeatureTypeConfigurationOgcApi collectionData = api.getData().getCollections().get(collectionId);
FeaturesCoreConfiguration coreConfiguration = collectionData.getExtension(FeaturesCoreConfiguration.class).filter(ExtensionConfiguration::isEnabled).filter(cfg -> cfg.getItemType().orElse(FeaturesCoreConfiguration.ItemType.feature) != FeaturesCoreConfiguration.ItemType.unknown).orElseThrow(() -> new NotFoundException(MessageFormat.format("Features are not supported in API ''{0}'', collection ''{1}''.", api.getId(), collectionId)));
int minimumPageSize = coreConfiguration.getMinimumPageSize();
int defaultPageSize = coreConfiguration.getDefaultPageSize();
int maxPageSize = coreConfiguration.getMaximumPageSize();
boolean showsFeatureSelfLink = coreConfiguration.getShowsFeatureSelfLink();
List<OgcApiQueryParameter> allowedParameters = getQueryParameters(extensionRegistry, api.getData(), "/collections/{collectionId}/items", collectionId);
FeatureQuery query = ogcApiFeaturesQuery.requestToFeatureQuery(api.getData(), collectionData, coreConfiguration.getDefaultEpsgCrs(), coreConfiguration.getCoordinatePrecision(), minimumPageSize, defaultPageSize, maxPageSize, toFlatMap(uriInfo.getQueryParameters()), allowedParameters);
FeaturesCoreQueriesHandler.QueryInputFeatures queryInput = new ImmutableQueryInputFeatures.Builder().from(getGenericQueryInput(api.getData())).collectionId(collectionId).query(query).featureProvider(providers.getFeatureProviderOrThrow(api.getData(), collectionData)).defaultCrs(coreConfiguration.getDefaultEpsgCrs()).defaultPageSize(Optional.of(defaultPageSize)).showsFeatureSelfLink(showsFeatureSelfLink).build();
return queryHandler.handle(FeaturesCoreQueriesHandlerImpl.Query.FEATURES, queryInput, requestContext);
}
use of de.ii.ogcapi.features.core.domain.FeaturesCoreConfiguration in project ldproxy by interactive-instruments.
the class QueryParameterLimitFeatures method getSchema.
@Override
public Schema getSchema(OgcApiDataV2 apiData) {
int apiHashCode = apiData.hashCode();
if (!schemaMap.containsKey(apiHashCode))
schemaMap.put(apiHashCode, new ConcurrentHashMap<>());
String collectionId = "*";
if (!schemaMap.get(apiHashCode).containsKey(collectionId)) {
Schema schema = new IntegerSchema();
Optional<Integer> minimumPageSize = apiData.getExtension(FeaturesCoreConfiguration.class).map(FeaturesCoreConfiguration::getMinimumPageSize);
if (minimumPageSize.isPresent())
schema.minimum(BigDecimal.valueOf(minimumPageSize.get()));
Optional<Integer> maxPageSize = apiData.getExtension(FeaturesCoreConfiguration.class).map(FeaturesCoreConfiguration::getMaximumPageSize);
if (maxPageSize.isPresent())
schema.maximum(BigDecimal.valueOf(maxPageSize.get()));
Optional<Integer> defaultPageSize = apiData.getExtension(FeaturesCoreConfiguration.class).map(FeaturesCoreConfiguration::getDefaultPageSize);
if (defaultPageSize.isPresent())
schema.setDefault(BigDecimal.valueOf(defaultPageSize.get()));
schemaMap.get(apiHashCode).put(collectionId, schema);
}
return schemaMap.get(apiHashCode).get(collectionId);
}
use of de.ii.ogcapi.features.core.domain.FeaturesCoreConfiguration in project ldproxy by interactive-instruments.
the class QueryParameterLimitFeatures method validateSchema.
@Override
public Optional<String> validateSchema(OgcApiDataV2 apiData, Optional<String> collectionId, List<String> values) {
if (values.size() != 1)
return Optional.of(String.format("Parameter value '%s' is invalid for parameter '%s': The must be a single value.", values, getName()));
int limit;
try {
limit = Integer.parseInt(values.get(0));
} catch (NumberFormatException exception) {
return Optional.of(String.format("Parameter value '%s' is invalid for parameter '%s': The value is not an integer.", values, getName()));
}
ExtendableConfiguration context = collectionId.isPresent() ? apiData.getCollections().get(collectionId.get()) : apiData;
Optional<Integer> minimumPageSize = context.getExtension(FeaturesCoreConfiguration.class).map(FeaturesCoreConfiguration::getMinimumPageSize);
if (minimumPageSize.isPresent() && limit < minimumPageSize.get())
return Optional.of(String.format("Parameter value '%s' is invalid for parameter '%s': The value is smaller than the minimum value '%d'.", values, getName(), minimumPageSize.get()));
return Optional.empty();
}
Aggregations