Skip to content

Commit

Permalink
Merge pull request #50684 from rldhont/backport-49438-to-release-3_28
Browse files Browse the repository at this point in the history
[Backport release-3_28] [Fix] Server WFS: Date time with ISO Date time field format
  • Loading branch information
elpaso committed Dec 11, 2022
2 parents 7d436ac + 59afc93 commit ce56631
Show file tree
Hide file tree
Showing 13 changed files with 2,319 additions and 383 deletions.
14 changes: 10 additions & 4 deletions src/server/services/wfs/qgswfsdescribefeaturetype.cpp
Expand Up @@ -286,12 +286,18 @@ namespace QgsWfs
const QgsEditorWidgetSetup setup = field.editorWidgetSetup();
if ( setup.type() == QStringLiteral( "DateTime" ) )
{
// Get editor widget setup config
const QVariantMap config = setup.config();
const QString fieldFormat = config.value( QStringLiteral( "field_format" ), QgsDateTimeFieldFormatter::defaultFormat( field.type() ) ).toString();
if ( fieldFormat == QLatin1String( "yyyy-MM-dd" ) )
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "date" ) );
else if ( fieldFormat == QLatin1String( "HH:mm:ss" ) )
// Get field format from editor widget setup config
const QString fieldFormat = config.value(
QStringLiteral( "field_format" ),
QgsDateTimeFieldFormatter::defaultFormat( field.type() )
).toString();
// Define type from field format
if ( fieldFormat == QgsDateTimeFieldFormatter::TIME_FORMAT ) // const TIME_FORMAT
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "time" ) );
else if ( fieldFormat == QLatin1String( "yyyy-MM-dd" ) ) // QgsDateTimeFieldFormatter provide a local date format
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "date" ) );
else
attElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "dateTime" ) );
}
Expand Down
25 changes: 23 additions & 2 deletions src/server/services/wfs/qgswfsgetfeature.cpp
Expand Up @@ -1580,14 +1580,35 @@ namespace QgsWfs

if ( setup.type() == QStringLiteral( "DateTime" ) )
{
// For time fields use const TIME_FORMAT
if ( value.type() == QVariant::Time )
{
return value.toTime().toString( QgsDateTimeFieldFormatter::TIME_FORMAT );
}

// Get editor widget setup config
const QVariantMap config = setup.config();
const QString fieldFormat = config.value( QStringLiteral( "field_format" ), QgsDateTimeFieldFormatter::defaultFormat( value.type() ) ).toString();
// Get field format, for ISO format then use const display format
// else use field format saved in editor widget setup config
const QString fieldFormat =
config.value( QStringLiteral( "field_iso_format" ), false ).toBool() ?
QgsDateTimeFieldFormatter::DISPLAY_FOR_ISO_FORMAT :
config.value( QStringLiteral( "field_format" ), QgsDateTimeFieldFormatter::defaultFormat( value.type() ) ).toString();

// Convert value to date time
QDateTime date = value.toDateTime();

// if not valid try to convert to date with field format
if ( !date.isValid() )
{
date = QDateTime::fromString( value.toString(), fieldFormat );
}
// if the date is valid, convert to string with field format
if ( date.isValid() )
{
return date.toString( fieldFormat );
}
// else provide the value as string
return value.toString();
}
else if ( setup.type() == QStringLiteral( "Range" ) )
{
Expand Down
29 changes: 29 additions & 0 deletions tests/src/python/test_qgsserver_wfs.py
Expand Up @@ -901,6 +901,35 @@ def test_getFeatureFeatureEnvelopeCrs(self):
self.assertEqual([c[:4] for c in e.findall('.//')[0].text.split(' ')], ['7.25', '44.7'])
self.assertEqual([c[:4] for c in e.findall('.//')[1].text.split(' ')], ['7.29', '44.8'])

def test_describeFeatureTypeDateTime(self):
"""Test DescribeFeatureType with dateTime fields"""
project_file = "../qgis_server_accesscontrol/project_with_dimensions.qgs"
self.wfs_request_compare("DescribeFeatureType", '1.0.0', "TYPENAME=Datetime_dim&",
'wfs_describeFeatureType_1_0_0_typename_datetime_dim', project_file=project_file)
self.wfs_request_compare("DescribeFeatureType", '1.1.0', "TYPENAME=Datetime_dim&",
'wfs_describeFeatureType_1_1_0_typename_datetime_dim', project_file=project_file)

self.wfs_request_compare("DescribeFeatureType", '1.1.0', "TYPENAME=datetime_str&",
'wfs_describeFeatureType_1_1_0_typename_datetime_str', project_file=project_file)

def test_GetFeature_with_datetime(self):
""" Test GetFeature with date-time data"""
project_file = "../qgis_server_accesscontrol/project_with_dimensions.qgs"

self.wfs_request_compare(
"GetFeature",
"1.0.0",
"TYPENAME=datetime_str&",
'wfs_getfeature_datetime_str',
project_file=project_file)

self.wfs_request_compare(
"GetFeature",
"1.0.0",
"TYPENAME=Datetime_dim&",
'wfs_getfeature_datetime',
project_file=project_file)


if __name__ == '__main__':
unittest.main()
@@ -0,0 +1,22 @@
Content-Length: 2176
Content-Type: text/xml; charset=utf-8

<schema xmlns:gml="http://www.opengis.net/gml" targetNamespace="http://www.qgis.org/gml" xmlns:qgs="http://www.qgis.org/gml" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ogc="http://www.opengis.net/ogc" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
<element type="qgs:Datetime_dimType" name="Datetime_dim" substitutionGroup="gml:_Feature"/>
<complexType name="Datetime_dimType">
<complexContent>
<extension base="gml:AbstractFeatureType">
<sequence>
<element maxOccurs="1" type="gml:PointPropertyType" minOccurs="0" name="geometry"/>
<element type="long" name="fid"/>
<element type="int" nillable="true" name="id"/>
<element type="date" nillable="true" name="date"/>
<element type="time" nillable="true" name="time"/>
<element type="dateTime" nillable="true" name="datetime"/>
<element type="string" nillable="true" name="date_time"/>
</sequence>
</extension>
</complexContent>
</complexType>
</schema>
@@ -0,0 +1,22 @@
Content-Length: 2176
Content-Type: text/xml; charset=utf-8

<schema xmlns:gml="http://www.opengis.net/gml" targetNamespace="http://www.qgis.org/gml" xmlns:qgs="http://www.qgis.org/gml" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ogc="http://www.opengis.net/ogc" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd"/>
<element type="qgs:Datetime_dimType" name="Datetime_dim" substitutionGroup="gml:_Feature"/>
<complexType name="Datetime_dimType">
<complexContent>
<extension base="gml:AbstractFeatureType">
<sequence>
<element maxOccurs="1" type="gml:PointPropertyType" minOccurs="0" name="geometry"/>
<element type="long" name="fid"/>
<element type="int" nillable="true" name="id"/>
<element type="date" nillable="true" name="date"/>
<element type="time" nillable="true" name="time"/>
<element type="dateTime" nillable="true" name="datetime"/>
<element type="string" nillable="true" name="date_time"/>
</sequence>
</extension>
</complexContent>
</complexType>
</schema>
@@ -0,0 +1,21 @@
Content-Length: 2176
Content-Type: text/xml; charset=utf-8

<schema xmlns:gml="http://www.opengis.net/gml" targetNamespace="http://www.qgis.org/gml" xmlns:qgs="http://www.qgis.org/gml" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ogc="http://www.opengis.net/ogc" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd"/>
<element type="qgs:datetime_strType" name="datetime_str" substitutionGroup="gml:_Feature"/>
<complexType name="datetime_strType">
<complexContent>
<extension base="gml:AbstractFeatureType">
<sequence>
<element maxOccurs="1" type="gml:PointPropertyType" minOccurs="0" name="geometry"/>
<element type="int" nillable="true" name="id"/>
<element type="date" nillable="true" name="date"/>
<element type="time" nillable="true" name="time"/>
<element type="dateTime" nillable="true" name="datetime"/>
<element type="dateTime" nillable="true" name="date_time"/>
</sequence>
</extension>
</complexContent>
</complexType>
</schema>
209 changes: 209 additions & 0 deletions tests/testdata/qgis_server/wfs_getfeature_datetime_1_0_0.txt
@@ -0,0 +1,209 @@
Content-Type: text/xml; subtype=gml/2.1.2; charset=utf-8

<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:qgs="http://www.qgis.org/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd http://www.qgis.org/gml ?">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates cs="," ts=" ">-7.99492,37.4402 -0.855025,43.0264</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<qgs:Datetime_dim fid="Datetime_dim.1">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates cs="," ts=" ">-7.9293612,43.0263943 -7.9293612,43.0263943</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<qgs:geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
<coordinates xmlns="http://www.opengis.net/gml" cs="," ts=" ">-7.9293612,43.0263943</coordinates>
</Point>
</qgs:geometry>
<qgs:fid>1</qgs:fid>
<qgs:id>0</qgs:id>
<qgs:date>2021-05-31</qgs:date>
<qgs:time>10:00:00</qgs:time>
<qgs:datetime>2021-05-31 10:00:00</qgs:datetime>
<qgs:date_time>2021-05-31T10:00:00</qgs:date_time>
</qgs:Datetime_dim>
</gml:featureMember>
<gml:featureMember>
<qgs:Datetime_dim fid="Datetime_dim.2">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates cs="," ts=" ">-2.63107078,37.98492015 -2.63107078,37.98492015</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<qgs:geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
<coordinates xmlns="http://www.opengis.net/gml" cs="," ts=" ">-2.63107078,37.98492015</coordinates>
</Point>
</qgs:geometry>
<qgs:fid>2</qgs:fid>
<qgs:id>1</qgs:id>
<qgs:date>2021-06-30</qgs:date>
<qgs:time>07:00:00</qgs:time>
<qgs:datetime>2021-06-30 07:00:00</qgs:datetime>
<qgs:date_time>2021-06-30T07:00:00</qgs:date_time>
</qgs:Datetime_dim>
</gml:featureMember>
<gml:featureMember>
<qgs:Datetime_dim fid="Datetime_dim.3">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates cs="," ts=" ">-3.95764769,39.67467133 -3.95764769,39.67467133</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<qgs:geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
<coordinates xmlns="http://www.opengis.net/gml" cs="," ts=" ">-3.95764769,39.67467133</coordinates>
</Point>
</qgs:geometry>
<qgs:fid>3</qgs:fid>
<qgs:id>2</qgs:id>
<qgs:date>2021-05-31</qgs:date>
<qgs:time>17:00:00</qgs:time>
<qgs:datetime>2021-05-31 17:00:00</qgs:datetime>
<qgs:date_time>2021-05-31T17:00:00</qgs:date_time>
</qgs:Datetime_dim>
</gml:featureMember>
<gml:featureMember>
<qgs:Datetime_dim fid="Datetime_dim.4">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates cs="," ts=" ">-0.85502457,37.82787511 -0.85502457,37.82787511</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<qgs:geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
<coordinates xmlns="http://www.opengis.net/gml" cs="," ts=" ">-0.85502457,37.82787511</coordinates>
</Point>
</qgs:geometry>
<qgs:fid>4</qgs:fid>
<qgs:id>3</qgs:id>
<qgs:date>2021-10-28</qgs:date>
<qgs:time>10:00:00</qgs:time>
<qgs:datetime>2021-10-28 10:00:00</qgs:datetime>
<qgs:date_time>2021-10-28T10:00:00</qgs:date_time>
</qgs:Datetime_dim>
</gml:featureMember>
<gml:featureMember>
<qgs:Datetime_dim fid="Datetime_dim.5">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates cs="," ts=" ">-6.16296928,42.57122133 -6.16296928,42.57122133</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<qgs:geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
<coordinates xmlns="http://www.opengis.net/gml" cs="," ts=" ">-6.16296928,42.57122133</coordinates>
</Point>
</qgs:geometry>
<qgs:fid>5</qgs:fid>
<qgs:id>4</qgs:id>
<qgs:date>2021-07-30</qgs:date>
<qgs:time>01:00:00</qgs:time>
<qgs:datetime>2021-07-30 01:00:00</qgs:datetime>
<qgs:date_time>2021-07-30T01:00:00</qgs:date_time>
</qgs:Datetime_dim>
</gml:featureMember>
<gml:featureMember>
<qgs:Datetime_dim fid="Datetime_dim.6">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates cs="," ts=" ">-6.67461865,37.4402079 -6.67461865,37.4402079</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<qgs:geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
<coordinates xmlns="http://www.opengis.net/gml" cs="," ts=" ">-6.67461865,37.4402079</coordinates>
</Point>
</qgs:geometry>
<qgs:fid>6</qgs:fid>
<qgs:id>5</qgs:id>
<qgs:date>2021-08-29</qgs:date>
<qgs:time>19:00:00</qgs:time>
<qgs:datetime>2021-08-29 19:00:00</qgs:datetime>
<qgs:date_time>2021-08-29T19:00:00</qgs:date_time>
</qgs:Datetime_dim>
</gml:featureMember>
<gml:featureMember>
<qgs:Datetime_dim fid="Datetime_dim.7">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates cs="," ts=" ">-3.77557445,40.4568878 -3.77557445,40.4568878</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<qgs:geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
<coordinates xmlns="http://www.opengis.net/gml" cs="," ts=" ">-3.77557445,40.4568878</coordinates>
</Point>
</qgs:geometry>
<qgs:fid>7</qgs:fid>
<qgs:id>6</qgs:id>
<qgs:date>2021-12-27</qgs:date>
<qgs:time>22:00:00</qgs:time>
<qgs:datetime>2021-12-27 22:00:00</qgs:datetime>
<qgs:date_time>2021-12-27T22:00:00</qgs:date_time>
</qgs:Datetime_dim>
</gml:featureMember>
<gml:featureMember>
<qgs:Datetime_dim fid="Datetime_dim.8">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates cs="," ts=" ">-1.98059826,42.02960468 -1.98059826,42.02960468</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<qgs:geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
<coordinates xmlns="http://www.opengis.net/gml" cs="," ts=" ">-1.98059826,42.02960468</coordinates>
</Point>
</qgs:geometry>
<qgs:fid>8</qgs:fid>
<qgs:id>7</qgs:id>
<qgs:date>2021-09-28</qgs:date>
<qgs:time>09:00:00</qgs:time>
<qgs:datetime>2021-09-28 09:00:00</qgs:datetime>
<qgs:date_time>2021-09-28T09:00:00</qgs:date_time>
</qgs:Datetime_dim>
</gml:featureMember>
<gml:featureMember>
<qgs:Datetime_dim fid="Datetime_dim.9">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates cs="," ts=" ">-7.99492105,38.86510435 -7.99492105,38.86510435</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<qgs:geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
<coordinates xmlns="http://www.opengis.net/gml" cs="," ts=" ">-7.99492105,38.86510435</coordinates>
</Point>
</qgs:geometry>
<qgs:fid>9</qgs:fid>
<qgs:id>8</qgs:id>
<qgs:date>2021-09-28</qgs:date>
<qgs:time>21:00:00</qgs:time>
<qgs:datetime>2021-09-28 21:00:00</qgs:datetime>
<qgs:date_time>2021-09-28T21:00:00</qgs:date_time>
</qgs:Datetime_dim>
</gml:featureMember>
<gml:featureMember>
<qgs:Datetime_dim fid="Datetime_dim.10">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates cs="," ts=" ">-6.79827095,37.93340218 -6.79827095,37.93340218</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<qgs:geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
<coordinates xmlns="http://www.opengis.net/gml" cs="," ts=" ">-6.79827095,37.93340218</coordinates>
</Point>
</qgs:geometry>
<qgs:fid>10</qgs:fid>
<qgs:id>9</qgs:id>
<qgs:date>2021-07-30</qgs:date>
<qgs:time>05:00:00</qgs:time>
<qgs:datetime>2021-07-30 05:00:00</qgs:datetime>
<qgs:date_time>2021-07-30T05:00:00</qgs:date_time>
</qgs:Datetime_dim>
</gml:featureMember>
</wfs:FeatureCollection>

0 comments on commit ce56631

Please sign in to comment.