143 QStringList conditions;
146 if ( dimensions.isEmpty() )
156 return QMetaType::Type::UnknownType;
163 auto refFieldCast = [&](
const QString &
fieldName, QMetaType::Type queryType, QMetaType::Type fieldType ) -> QString {
164 const auto fieldRealType { fieldTypeFromName(
fieldName, layer ) };
165 if ( fieldRealType == QMetaType::Type::UnknownType )
172 if ( fieldRealType == QMetaType::Type::QString )
175 if ( fieldType != queryType || fieldType == QMetaType::Type::QDate )
184 else if ( fieldType == queryType || fieldType == QMetaType::Type::QDate )
195 auto quoteValue = [](
const QString &value ) -> QString {
196 if ( value.length() == 10 )
208 ["eValue](
const QString &fieldBegin,
const QString &fieldEnd,
const QString &fieldBeginCasted,
const QString &fieldEndCasted,
const QString &queryBegin,
const QString &queryEnd ) -> QString {
212 if ( !queryBegin.isEmpty() && !queryEnd.isEmpty() )
215 if ( !fieldEndCasted.isEmpty() )
217 result = u
"( %1 IS NULL OR %2 <= %6 ) AND ( %4 IS NULL OR %5 >= %3 )"_s.arg( fieldBegin, fieldBeginCasted, quoteValue( queryBegin ), fieldEnd, fieldEndCasted, quoteValue( queryEnd ) );
221 result = u
"( %1 IS NULL OR ( %2 <= %3 AND %3 <= %4 ) )"_s.arg( fieldBegin, quoteValue( queryBegin ), fieldBeginCasted, quoteValue( queryEnd ) );
224 else if ( !queryBegin.isEmpty() )
226 if ( !fieldEndCasted.isEmpty() )
228 result = u
"( %1 IS NULL OR %2 >= %3 )"_s.arg( fieldEnd, fieldEndCasted, quoteValue( queryBegin ) );
232 result = u
"( %1 IS NULL OR %2 >= %3 )"_s.arg( fieldBegin, fieldBeginCasted, quoteValue( queryBegin ) );
237 result = u
"( %1 IS NULL OR %2 <= %3 )"_s.arg( fieldBegin, fieldBeginCasted, quoteValue( queryEnd ) );
243 QString testType { interval };
244 if ( interval.contains(
'/' ) )
246 const QStringList parts { interval.split(
'/' ) };
248 if ( testType.isEmpty() || testType ==
".."_L1 )
255 const bool inputQueryIsDateTime { testType.length() > 10 };
256 const QMetaType::Type queryType { inputQueryIsDateTime ? QMetaType::Type::QDateTime : QMetaType::Type::QDate };
259 if ( interval.contains(
'/' ) )
261 if ( !inputQueryIsDateTime )
265 for (
const auto &dimension : std::as_const( dimensions ) )
268 const QMetaType::Type fieldType { dimension.name.toLower() ==
"time"_L1 ? QMetaType::Type::QDateTime : QMetaType::Type::QDate };
270 const auto fieldBeginCasted { refFieldCast( dimension.fieldName, queryType, fieldType ) };
271 if ( fieldBeginCasted.isEmpty() )
280 const auto fieldEndCasted { refFieldCast( dimension.endFieldName, queryType, fieldType ) };
281 if ( !dateInterval.
begin().isValid() && !dateInterval.
end().isValid() )
287 conditions.push_back(
288 makeFilter( fieldBegin, fieldEnd, fieldBeginCasted, fieldEndCasted, dateInterval.
begin().toString( Qt::DateFormat::ISODate ), dateInterval.
end().toString( Qt::DateFormat::ISODate ) )
296 for (
const auto &dimension : std::as_const( dimensions ) )
299 const QMetaType::Type fieldType { dimension.name.toLower() ==
"time"_L1 ? QMetaType::Type::QDateTime : QMetaType::Type::QDate };
301 const auto fieldfBeginCasted { refFieldCast( dimension.fieldName, queryType, fieldType ) };
302 if ( fieldfBeginCasted.isEmpty() )
310 const auto fieldEndCasted { refFieldCast( dimension.endFieldName, queryType, fieldType ) };
311 if ( !dateTimeInterval.
begin().isValid() && !dateTimeInterval.
end().isValid() )
321 if ( fieldType == QMetaType::Type::QDate )
323 beginQuery = dateTimeInterval.
begin().date().toString( Qt::DateFormat::ISODate );
324 endQuery = dateTimeInterval.
end().date().toString( Qt::DateFormat::ISODate );
328 beginQuery = dateTimeInterval.
begin().toString( Qt::DateFormat::ISODate );
329 endQuery = dateTimeInterval.
end().toString( Qt::DateFormat::ISODate );
331 conditions.push_back( makeFilter( fieldBegin, fieldEnd, fieldfBeginCasted, fieldEndCasted, beginQuery, endQuery ) );
338 for (
const auto &dimension : std::as_const( dimensions ) )
341 const bool fieldIsDateTime { dimension.name.toLower() ==
"time"_L1 };
342 const QMetaType::Type fieldType { fieldIsDateTime ? QMetaType::Type::QDateTime : QMetaType::Type::QDate };
344 const auto fieldRefBegin { refFieldCast( dimension.fieldName, queryType, fieldType ) };
345 if ( fieldRefBegin.isEmpty() )
352 const auto fieldRefEnd { refFieldCast( dimension.endFieldName, queryType, fieldType ) };
359 if ( !inputQueryIsDateTime || !fieldIsDateTime )
361 QString castedInterval { interval };
363 if ( inputQueryIsDateTime )
365 castedInterval = QDate::fromString( castedInterval, Qt::DateFormat::ISODate ).toString( Qt::DateFormat::ISODate );
371 QString castedInterval { interval };
373 if ( !inputQueryIsDateTime )
375 castedInterval = QDateTime::fromString( castedInterval, Qt::DateFormat::ISODate ).toString( Qt::DateFormat::ISODate );
380 if ( !fieldRefEnd.isEmpty() )
382 condition = u
"( %1 IS NULL OR %2 <= %3 ) AND ( %5 IS NULL OR %3 <= %4 )"_s.arg( fieldBegin, fieldRefBegin, castedValue, fieldRefEnd, fieldEnd );
386 condition = u
"( %1 IS NULL OR %2 = %3 )"_s.arg( fieldBegin, fieldRefBegin, castedValue );
388 conditions.push_back( condition );
391 if ( !conditions.isEmpty() )
426 QDateTime min { minVal.toDateTime() };
427 QDateTime max { maxVal.toDateTime() };
428 if ( !dimInfo.endFieldName.isEmpty() )
437 QDateTime minEnd { minVal.toDateTime() };
438 QDateTime maxEnd { maxVal.toDateTime() };
439 if ( minEnd.isValid() )
441 min = std::min<QDateTime>( min, minEnd );
443 if ( maxEnd.isValid() )
445 max = std::max<QDateTime>( max, maxEnd );
453 if ( dimensions.isEmpty() )
463 for (
const auto &dimension : dimensions )
468 extent = range( dimension );
473 extent.
extend( range( dimension ) );
476 json ret = json::array();
477 const QString beginVal { extent.
begin().toString( Qt::DateFormat::ISODate ) };
478 const QString endVal { extent.
end().toString( Qt::DateFormat::ISODate ) };
480 if ( beginVal.isEmpty() && endVal.isEmpty() )
482 ret.push_back( {
nullptr,
nullptr } );
484 else if ( beginVal.isEmpty() )
486 ret.push_back( {
nullptr, endVal.toStdString() } );
488 else if ( endVal.isEmpty() )
490 ret.push_back( { beginVal.toStdString(),
nullptr } );
494 ret.push_back( { beginVal.toStdString(), endVal.toStdString() } );
498 catch ( std::exception &ex )
500 const QString errorMessage { u
"Error creating temporal extent: %1"_s.arg( ex.what() ) };