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 @@ -3,6 +3,7 @@
public enum FeatureId {
summary("summary"),
wfs_fields("wfs_fields"), // Query field based on pure wfs and given layer
wfs_field_value("wfs_field_value"),
wms_fields("wms_fields"), // Query field based on value from wms describe layer query
wave_buoy_first_data_available("wave_buoy_first_data_available"),
wave_buoy_latest_date("wave_buoy_latest_date"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
package au.org.aodn.ogcapi.server.core.model.ogc;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.*;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

@Schema(description = "Query parameters for feature requests")
@Data
@Builder
@SuperBuilder
@NoArgsConstructor(force = true, access = AccessLevel.PROTECTED) // Need when using @SuperBuilder
@EqualsAndHashCode
public class FeatureRequest implements Serializable {
// Define a fix name for fields, the geoserver data have all sorts of different name,
// map it here so that we hide the complexity of call from UI.
public enum PropertyName {
wildcard,
time;

public static PropertyName fromString(String input) {
if (input == null || "*".equals(input.trim())) {
return wildcard; // or throw exception / return default
}
return valueOf(input.trim());
}
}

@Schema(description = "Property to be return")
private List<String> properties;
private List<PropertyName> properties;

@Schema(description = "Only records that have a geometry that intersects the bounding box are selected. The bounding box is provided as four or six numbers, depending on whether the coordinate reference system includes a vertical axis (height or depth): * Lower left corner, coordinate axis 1 * Lower left corner, coordinate axis 2 * Minimum value, coordinate axis 3 (optional) * Upper right corner, coordinate axis 1 * Upper right corner, coordinate axis 2 * Maximum value, coordinate axis 3 (optional) The coordinate reference system of the values is WGS 84 long/lat (http://www.opengis.net/def/crs/OGC/1.3/CRS84) unless a different coordinate reference system is specified in the parameter `bbox-crs`. For WGS 84 longitude/latitude the values are in most cases the sequence of minimum longitude, minimum latitude, maximum longitude and maximum latitude. However, in cases where the box spans the antimeridian the first value (west-most box edge) is larger than the third value (east-most box edge). If the vertical axis is included, the third and the sixth number are the bottom and the top of the 3-dimensional bounding box. If a record has multiple spatial geometry properties, it is the decision of the server whether only a single spatial geometry property is used to determine the extent or all relevant geometries.")
private List<BigDecimal> bbox;
Expand Down Expand Up @@ -44,6 +58,7 @@ public class FeatureRequest implements Serializable {
@Schema(description = "Enable or disable geoserver whitelist")
@Builder.Default
private Boolean enableGeoServerWhiteList = Boolean.TRUE;

/**
* Make sure if json indicate null, we still return true by default
* @return - Utility function with default
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package au.org.aodn.ogcapi.server.core.model.ogc.wfs;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@Builder
@EqualsAndHashCode
public class WfsField {
@JsonProperty("label")
private String label;

@JsonProperty("name")
private String name;

@JsonProperty("type")
private String type;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package au.org.aodn.ogcapi.server.core.model.ogc.wfs;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;

import java.util.List;

@Data
@Builder
public class WfsFields {

@JsonProperty("typename")
private String typename;

@JsonProperty("fields")
private List<WfsField> fields;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import au.org.aodn.ogcapi.server.core.model.StacCollectionModel;
import au.org.aodn.ogcapi.server.core.model.SearchSuggestionsModel;
import au.org.aodn.ogcapi.server.core.model.enumeration.*;
import au.org.aodn.ogcapi.server.core.model.ogc.FeatureRequest;
import au.org.aodn.ogcapi.server.core.parser.elastic.CQLToElasticFilterFactory;
import au.org.aodn.ogcapi.server.core.parser.elastic.QueryHandler;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
Expand Down Expand Up @@ -632,7 +633,7 @@ protected static FieldValue toFieldValue(String s) {
// }

@Override
public SearchResult<FeatureGeoJSON> searchFeatureSummary(String collectionId, List<String> properties, String filter) {
public SearchResult<FeatureGeoJSON> searchFeatureSummary(String collectionId, List<FeatureRequest.PropertyName> properties, String filter) {
try {
SearchRequest searchRequest = new SearchRequest.Builder()
.index(dataIndexName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import au.org.aodn.ogcapi.server.core.model.enumeration.CQLCrsType;
import au.org.aodn.ogcapi.server.core.model.enumeration.FeatureId;
import au.org.aodn.ogcapi.server.core.model.enumeration.OGCMediaTypeMapper;
import au.org.aodn.ogcapi.server.core.model.ogc.FeatureRequest;
import au.org.aodn.ogcapi.server.core.parser.stac.CQLToStacFilterFactory;
import au.org.aodn.ogcapi.server.tile.RestApi;
import org.geotools.filter.text.commons.CompilerUtil;
Expand Down Expand Up @@ -39,9 +40,9 @@ public abstract class OGCApiService {
public abstract List<String> getConformanceDeclaration();

public ResponseEntity<FeatureCollectionGeoJSON> getFeature(String collectionId,
FeatureId fid,
List<String> properties,
String filter) throws Exception {
FeatureId fid,
List<FeatureRequest.PropertyName> properties,
String filter) throws Exception {
switch(fid) {
case summary -> {
var result = search.searchFeatureSummary(collectionId, properties, filter);
Expand Down Expand Up @@ -160,9 +161,9 @@ else if (datetime.contains("/") && !datetime.contains("..")) {
}
/**
* Convert the bbox parameter to CQL
* @param bbox
* @param filter
* @return
* @param bbox - Bounding box
* @param filter - CQL filter string
* @return - String format as cql
*/
public static String processBBoxParameter(String fieldName, List<BigDecimal> bbox, String filter) {
String f = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import au.org.aodn.ogcapi.features.model.FeatureGeoJSON;
import au.org.aodn.ogcapi.server.core.model.StacCollectionModel;
import au.org.aodn.ogcapi.server.core.model.enumeration.CQLCrsType;
import au.org.aodn.ogcapi.server.core.model.ogc.FeatureRequest;
import co.elastic.clients.transport.endpoints.BinaryResponse;
import org.springframework.http.ResponseEntity;

Expand All @@ -17,7 +18,7 @@ public interface Search {
ElasticSearchBase.SearchResult<StacCollectionModel> searchCollections(String id);
ElasticSearchBase.SearchResult<StacCollectionModel> searchCollections(List<String> ids, String sortBy);
ElasticSearchBase.SearchResult<StacCollectionModel> searchAllCollections(String sortBy) throws Exception;
ElasticSearchBase.SearchResult<FeatureGeoJSON>searchFeatureSummary(String collectionId, List<String> properties, String filter) throws Exception;
ElasticSearchBase.SearchResult<FeatureGeoJSON>searchFeatureSummary(String collectionId, List<FeatureRequest.PropertyName> properties, String filter) throws Exception;

ElasticSearchBase.SearchResult<StacCollectionModel> searchByParameters(
List<String> targets,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package au.org.aodn.ogcapi.server.core.service.wfs;

import au.org.aodn.ogcapi.server.core.model.ogc.FeatureRequest;
import au.org.aodn.ogcapi.server.core.model.ogc.wfs.WFSFieldModel;
import au.org.aodn.ogcapi.server.core.model.ogc.wfs.WfsField;
import au.org.aodn.ogcapi.server.core.model.ogc.wfs.WfsFields;
import au.org.aodn.ogcapi.server.core.model.ogc.wms.DescribeLayerResponse;
import au.org.aodn.ogcapi.server.core.service.wms.WmsServer;
import au.org.aodn.ogcapi.server.core.util.DatetimeUtils;
Expand Down Expand Up @@ -42,17 +43,17 @@ public DownloadWfsDataService(
/**
* Build CQL filter for temporal and spatial constraints
*/
private String buildCqlFilter(String startDate, String endDate, Object multiPolygon, WFSFieldModel wfsFieldModel) {
private String buildCqlFilter(String startDate, String endDate, Object multiPolygon, WfsFields wfsFieldModel) {
StringBuilder cqlFilter = new StringBuilder();

if (wfsFieldModel == null || wfsFieldModel.getFields() == null) {
return cqlFilter.toString();
}

List<WFSFieldModel.Field> fields = wfsFieldModel.getFields();
List<WfsField> fields = wfsFieldModel.getFields();

// Find temporal field
Optional<WFSFieldModel.Field> temporalField = fields.stream()
Optional<WfsField> temporalField = fields.stream()
.filter(field -> "dateTime".equals(field.getType()) || "date".equals(field.getType()))
.findFirst();

Expand All @@ -66,7 +67,7 @@ private String buildCqlFilter(String startDate, String endDate, Object multiPoly
}

// Find geometry field
Optional<WFSFieldModel.Field> geometryField = fields.stream()
Optional<WfsField> geometryField = fields.stream()
.filter(field -> "geometrypropertytype".equals(field.getType()))
.findFirst();

Expand Down Expand Up @@ -106,22 +107,22 @@ public String prepareWfsRequestUrl(

String wfsServerUrl;
String wfsTypeName;
WFSFieldModel wfsFieldModel;
WfsFields wfsFieldModel;

// Try to get WFS details from DescribeLayer first, then fallback to searching by layer name
if (describeLayerResponse != null && describeLayerResponse.getLayerDescription().getWfs() != null) {
wfsServerUrl = describeLayerResponse.getLayerDescription().getWfs();
wfsTypeName = describeLayerResponse.getLayerDescription().getQuery().getTypeName();

wfsFieldModel = wfsServer.getDownloadableFields(uuid, FeatureRequest.builder().layerName(wfsTypeName).build(), wfsServerUrl);
wfsFieldModel = wfsServer.getDownloadableFields(uuid, WfsServer.WfsFeatureRequest.builder().layerName(wfsTypeName).server(wfsServerUrl).build());
log.info("WFSFieldModel by describeLayer: {}", wfsFieldModel);
} else {
Optional<String> featureServerUrl = wfsServer.getFeatureServerUrlByTitle(uuid, layerName);

if (featureServerUrl.isPresent()) {
wfsServerUrl = featureServerUrl.get();
wfsTypeName = layerName;
wfsFieldModel = wfsServer.getDownloadableFields(uuid, FeatureRequest.builder().layerName(wfsTypeName).build(), wfsServerUrl);
wfsFieldModel = wfsServer.getDownloadableFields(uuid, WfsServer.WfsFeatureRequest.builder().layerName(wfsTypeName).server(wfsServerUrl).build());
log.info("WFSFieldModel by wfs typename: {}", wfsFieldModel);
} else {
throw new IllegalArgumentException("No WFS server URL found for the given UUID and layer name");
Expand Down
Loading
Loading