11package au .org .aodn .ogcapi .server .core .service .geoserver .wfs ;
22
33import au .org .aodn .ogcapi .server .core .model .ogc .FeatureRequest ;
4- import au .org .aodn .ogcapi .server .core .model .ogc .wfs .WfsField ;
5- import au .org .aodn .ogcapi .server .core .model .ogc .wfs .WfsFields ;
6- import au .org .aodn .ogcapi .server .core .util .DatetimeUtils ;
7- import au .org .aodn .ogcapi .server .core .util .GeometryUtils ;
4+ import au .org .aodn .ogcapi .server .core .service .geoserver .Server ;
85import lombok .extern .slf4j .Slf4j ;
96import org .springframework .beans .factory .annotation .Qualifier ;
107import org .springframework .beans .factory .annotation .Value ;
2118
2219@ Slf4j
2320@ Service
24- public class DownloadWfsDataService {
25- private final WfsServer wfsServer ;
21+ public class DownloadWfsDataService extends Server {
2622 private final RestTemplate restTemplate ;
2723 private final HttpEntity <?> pretendUserEntity ;
2824 private final int chunkSize ;
@@ -33,65 +29,11 @@ public DownloadWfsDataService(
3329 @ Qualifier ("pretendUserEntity" ) HttpEntity <?> pretendUserEntity ,
3430 @ Value ("${app.sse.chunkSize:16384}" ) int chunkSize
3531 ) {
36- this . wfsServer = wfsServer ;
32+ super ( wfsServer ) ;
3733 this .restTemplate = restTemplate ;
3834 this .pretendUserEntity = pretendUserEntity ;
3935 this .chunkSize = chunkSize ;
4036 }
41-
42- /**
43- * Build CQL filter for temporal and spatial constraints
44- */
45- protected String buildCqlFilter (String startDate , String endDate , Object multiPolygon , WfsFields wfsFieldModel ) {
46- StringBuilder cqlFilter = new StringBuilder ();
47-
48- if (wfsFieldModel == null || wfsFieldModel .getFields () == null ) {
49- return cqlFilter .toString ();
50- }
51-
52- List <WfsField > fields = wfsFieldModel .getFields ();
53-
54- // Possible to have multiple days, better to consider all
55- List <WfsField > temporalField = fields .stream ()
56- .filter (field -> "dateTime" .equals (field .getType ()) || "date" .equals (field .getType ()))
57- .toList ();
58-
59- // Add temporal filter only if both dates are specified
60- if (!temporalField .isEmpty () && startDate != null && !startDate .isEmpty () && endDate != null && !endDate .isEmpty ()) {
61- List <String > cqls = new ArrayList <>();
62- temporalField .forEach (temp ->
63- cqls .add (String .format ("(%s DURING %sT00:00:00Z/%sT23:59:59Z)" , temp .getName (), startDate , endDate ))
64- );
65- cqlFilter .append ("(" ).append (String .join (" OR " , cqls )).append (")" );
66- }
67-
68- // Find geometry field
69- Optional <WfsField > geometryField = fields .stream ()
70- .filter (field -> "geometrypropertytype" .equalsIgnoreCase (field .getType ()))
71- .findFirst ();
72-
73- // Add spatial filter
74- if (geometryField .isPresent () && multiPolygon != null ) {
75- String fieldName = geometryField .get ().getName ();
76-
77- String wkt = GeometryUtils .convertToWkt (multiPolygon );
78-
79- if ((wkt != null ) && !cqlFilter .isEmpty ()) {
80- cqlFilter .append (" AND " );
81- }
82-
83- if (wkt != null ) {
84- cqlFilter .append ("INTERSECTS(" )
85- .append (fieldName )
86- .append ("," )
87- .append (wkt )
88- .append (")" );
89- }
90- }
91-
92- return cqlFilter .toString ();
93- }
94-
9537 /**
9638 * Does collection lookup, WFS validation, field retrieval, and URL building
9739 */
@@ -104,46 +46,30 @@ public String prepareWfsRequestUrl(
10446 String layerName ,
10547 String outputFormat ) {
10648
107- String wfsServerUrl ;
108- String wfsTypeName ;
109- WfsFields wfsFieldModel ;
11049
11150 // Get WFS server URL and field model for the given UUID and layer name
11251 Optional <String > featureServerUrl = wfsServer .getFeatureServerUrl (uuid , layerName );
11352
11453 // Get the wfs fields to build the CQL filter
11554 if (featureServerUrl .isPresent ()) {
116- wfsServerUrl = featureServerUrl .get ();
117- wfsTypeName = layerName ;
118- wfsFieldModel = wfsServer .getDownloadableFields (
119- uuid ,
120- WfsServer .WfsFeatureRequest .builder ()
121- .layerName (wfsTypeName )
122- .server (wfsServerUrl )
123- .build ()
124- );
125- log .debug ("WFSFieldModel by wfs typename: {}" , wfsFieldModel );
126- } else {
127- throw new IllegalArgumentException ("No WFS server URL found for the given UUID and layer name" );
128- }
129-
130- // Validate start and end dates
131- String validStartDate = DatetimeUtils .validateAndFormatDate (startDate , true );
132- String validEndDate = DatetimeUtils .validateAndFormatDate (endDate , false );
55+ String wfsServerUrl = featureServerUrl .get ();
13356
134- // Build CQL filter
135- String cqlFilter = buildCqlFilter (validStartDate , validEndDate , multiPolygon , wfsFieldModel );
57+ // Build CQL filter
58+ String cqlFilter = buildCqlFilter (wfsServerUrl , uuid , layerName , startDate , endDate , multiPolygon );
13659
137- // Build final WFS request URL
138- String wfsRequestUrl = wfsServer .createWfsRequestUrl (
139- wfsServerUrl ,
140- wfsTypeName ,
141- fields ,
142- cqlFilter ,
143- outputFormat );
60+ // Build final WFS request URL
61+ String wfsRequestUrl = wfsServer .createWfsRequestUrl (
62+ wfsServerUrl ,
63+ layerName ,
64+ fields ,
65+ cqlFilter ,
66+ outputFormat );
14467
145- log .info ("Prepared WFS request URL: {}" , wfsRequestUrl );
146- return wfsRequestUrl ;
68+ log .info ("Prepared WFS request URL: {}" , wfsRequestUrl );
69+ return wfsRequestUrl ;
70+ } else {
71+ throw new IllegalArgumentException ("No WFS server URL found for the given UUID and layer name" );
72+ }
14773 }
14874
14975 /**
0 commit comments