Skip to content

Commit

Permalink
gml_[item]_type: modify Date semantics, and add Time and DateTime
Browse files Browse the repository at this point in the history
Currently, for vector features, we have a Date datatype that is used
indifferently for Date, Time, DateTime, which can cause approximations
in GML or other output formats (such as OGR GeoJSON), since the output
doesn't really know the exact input.
This change modifies the semantics of Date to mean date, without time,
and add Time (time, without date) and DateTime. The type autodetection
is modified in the MSSQL2008, OGR, Oracle and PostGIS backends. On the
output side, the WFS/GML and OGR output are modified to take into account
those 3 separate types.
  • Loading branch information
rouault committed Oct 27, 2019
1 parent 2bd9c0d commit e91a4e5
Show file tree
Hide file tree
Showing 25 changed files with 329 additions and 149 deletions.
13 changes: 9 additions & 4 deletions mapgml.c
Original file line number Diff line number Diff line change
Expand Up @@ -1024,14 +1024,14 @@ static void msGMLWriteItem(FILE *stream, gmlItemObj *item,
tag_name = item->name;
if(strchr(tag_name, ':') != NULL) add_namespace = MS_FALSE;

if( item->type && EQUAL(item->type, "Date") ) {
if( item->type && (EQUAL(item->type, "Date") ||
EQUAL(item->type, "DateTime") ||
EQUAL(item->type, "Time")) ) {
struct tm tm;
if( msParseTime(value, &tm) == MS_TRUE ) {
const char* pszStartTag = "";
const char* pszEndTag = "";
int timeresolution;

timeresolution = msTimeGetResolution(value);
encoded_value = (char*) msSmallMalloc(256);
if( outputformat == OWS_GML32 ) {
if( pszFID != NULL )
Expand All @@ -1040,11 +1040,16 @@ static void msGMLWriteItem(FILE *stream, gmlItemObj *item,
pszEndTag = "</gml:timePosition>";
}

if( timeresolution == TIME_RESOLUTION_DAY )
if( EQUAL(item->type, "Date") )
snprintf(encoded_value, 256, "%s%04d-%02d-%02d%s",
pszStartTag,
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
pszEndTag);
else if( EQUAL(item->type, "Time") )
snprintf(encoded_value, 256, "%s%02d:%02d:%02dZ%s",
pszStartTag,
tm.tm_hour, tm.tm_min, tm.tm_sec,
pszEndTag);
else
snprintf(encoded_value, 256, "%s%04d-%02d-%02dT%02d:%02d:%02dZ%s",
pszStartTag,
Expand Down
6 changes: 5 additions & 1 deletion mapmssql2008.c
Original file line number Diff line number Diff line change
Expand Up @@ -886,9 +886,13 @@ static int columnName(msODBCconn *conn, int index, char *buffer, int bufferLengt
break;

case SQL_TYPE_DATE:
gml_type = "Date";
break;
case SQL_TYPE_TIME:
gml_type = "Time";
break;
case SQL_TYPE_TIMESTAMP:
gml_type = "Date";
gml_type = "DateTime";
break;

case SQL_BIT:
Expand Down
6 changes: 5 additions & 1 deletion mapogr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2719,9 +2719,13 @@ msOGRPassThroughFieldDefinitions( layerObj *layer, msOGRFileInfo *psInfo )
break;

case OFTDate:
gml_type = "Date";
break;
case OFTTime:
gml_type = "Time";
break;
case OFTDateTime:
gml_type = "Date";
gml_type = "DateTime";
break;

default:
Expand Down
4 changes: 4 additions & 0 deletions mapogroutput.c
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,10 @@ int msOGRWriteFromQuery( mapObj *map, outputFormatObj *format, int sendheaders )
else if( EQUAL(item->type,"Character") )
eType = OFTString;
else if( EQUAL(item->type,"Date") )
eType = OFTDate;
else if( EQUAL(item->type,"Time") )
eType = OFTTime;
else if( EQUAL(item->type,"DateTime") )
eType = OFTDateTime;
else if( EQUAL(item->type,"Boolean") )
eType = OFTInteger;
Expand Down
6 changes: 5 additions & 1 deletion maporaclespatial.c
Original file line number Diff line number Diff line change
Expand Up @@ -2935,12 +2935,16 @@ msOracleSpatialGetFieldDefn( layerObj *layer,

case SQLT_DAT:
case SQLT_DATE:
gml_type = "Date";
break;
case SQLT_TIMESTAMP:
case SQLT_TIMESTAMP_TZ:
case SQLT_TIMESTAMP_LTZ:
gml_type = "DateTime";
break;
case SQLT_TIME:
case SQLT_TIME_TZ:
gml_type = "Date";
gml_type = "Time";
break;

default:
Expand Down
8 changes: 6 additions & 2 deletions mappostgis.c
Original file line number Diff line number Diff line change
Expand Up @@ -3199,6 +3199,7 @@ int msPostGISLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record)
#define VARCHAROID 1043
#define DATEOID 1082
#define TIMEOID 1083
#define TIMETZOID 1266
#define TIMESTAMPOID 1114
#define TIMESTAMPTZOID 1184
#define NUMERICOID 1700
Expand Down Expand Up @@ -3260,9 +3261,12 @@ msPostGISPassThroughFieldDefinitions( layerObj *layer,
sprintf( gml_width, "%d", (fmod - 4) >> 16 );
sprintf( gml_precision, "%d", ((fmod-4) & 0xFFFF) );
}
} else if( oid == DATEOID
|| oid == TIMESTAMPOID || oid == TIMESTAMPTZOID ) {
} else if( oid == DATEOID ) {
gml_type = "Date";
} else if( oid == TIMEOID || oid == TIMETZOID ) {
gml_type = "Time";
} else if( oid == TIMESTAMPOID || oid == TIMESTAMPTZOID ) {
gml_type = "DateTime";
}

snprintf( md_item_name, sizeof(md_item_name), "gml_%s_type", item );
Expand Down
10 changes: 6 additions & 4 deletions maptime.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ typedef struct {
MS_TIME_RESOLUTION resolution;
} timeFormatObj;

#define MS_NUMTIMEFORMATS 13

timeFormatObj ms_timeFormats[MS_NUMTIMEFORMATS] = {
static timeFormatObj ms_timeFormats[] = {
{"^[0-9]{8}", NULL, "%Y%m%d","YYYYMMDD",TIME_RESOLUTION_DAY},
{"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z", NULL, "%Y-%m-%dT%H:%M:%SZ","YYYY-MM-DDTHH:MM:SSZ",TIME_RESOLUTION_SECOND},
{"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}", NULL, "%Y-%m-%dT%H:%M:%S", "YYYY-MM-DDTHH:MM:SS",TIME_RESOLUTION_SECOND},
Expand All @@ -60,9 +58,13 @@ timeFormatObj ms_timeFormats[MS_NUMTIMEFORMATS] = {
{"^[0-9]{4}-[0-9]{2}", NULL, "%Y-%m", "YYYY-MM",TIME_RESOLUTION_MONTH},
{"^[0-9]{4}", NULL, "%Y", "YYYY",TIME_RESOLUTION_YEAR},
{"^T[0-9]{2}:[0-9]{2}:[0-9]{2}Z", NULL, "T%H:%M:%SZ", "THH:MM:SSZ",TIME_RESOLUTION_SECOND},
{"^T[0-9]{2}:[0-9]{2}:[0-9]{2}", NULL, "T%H:%M:%S", "THH:MM:SS", TIME_RESOLUTION_SECOND}
{"^T[0-9]{2}:[0-9]{2}:[0-9]{2}", NULL, "T%H:%M:%S", "THH:MM:SS", TIME_RESOLUTION_SECOND},
{"^[0-9]{2}:[0-9]{2}:[0-9]{2}Z", NULL, "%H:%M:%SZ", "HH:MM:SSZ", TIME_RESOLUTION_SECOND},
{"^[0-9]{2}:[0-9]{2}:[0-9]{2}", NULL, "%H:%M:%S", "HH:MM:SS", TIME_RESOLUTION_SECOND}
};

#define MS_NUMTIMEFORMATS (int)(sizeof(ms_timeFormats)/sizeof(ms_timeFormats[0]))

int *ms_limited_pattern = NULL;
int ms_num_limited_pattern;

Expand Down
7 changes: 6 additions & 1 deletion mapwfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,10 @@ static const char* msWFSMapServTypeToXMLType(const char* type)
element_type = "string";
else if( EQUAL(type,"Date") )
element_type = "date";
else if( EQUAL(type,"Time") )
element_type = "time";
else if( EQUAL(type,"DateTime") )
element_type = "dateTime";
else if( EQUAL(type,"Boolean") )
element_type = "boolean";
return element_type;
Expand All @@ -1084,7 +1088,8 @@ static void msWFSWriteItemElement(FILE *stream, gmlItemObj *item, const char *ta

if(item->type)
{
if( outputformat == OWS_GML32_SFE_SCHEMA && EQUAL(item->type,"Date") )
if( outputformat == OWS_GML32_SFE_SCHEMA &&
(EQUAL(item->type,"Date") || EQUAL(item->type,"Time") || EQUAL(item->type,"DateTime")) )
element_type = "gml:TimeInstantType";
else
element_type = msWFSMapServTypeToXMLType(item->type);
Expand Down
4 changes: 2 additions & 2 deletions msautotest/wxs/data/alltypes.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
aint,str,areal,adate
1,a,2.4,"2013/10/26 12:00:00"
aint,str,areal,adatetime,adate,atime
1,a,2.4,"2013/10/26 12:00:00","2013/10/26","12:00:00"
2 changes: 1 addition & 1 deletion msautotest/wxs/data/alltypes.csvt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Integer,String,Real,DateTime
Integer,String,Real,DateTime,Date,Time
2 changes: 2 additions & 0 deletions msautotest/wxs/expected/wfs_alltypes_describefeaturetype.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ Content-Type: text/xml; subtype=gml/3.1.1; charset=UTF-8
<element name="aint" minOccurs="0" type="integer"/>
<element name="str" minOccurs="0" type="string"/>
<element name="areal" minOccurs="0" type="double"/>
<element name="adatetime" minOccurs="0" type="dateTime"/>
<element name="adate" minOccurs="0" type="date"/>
<element name="atime" minOccurs="0" type="time"/>
</sequence>
</extension>
</complexContent>
Expand Down
35 changes: 35 additions & 0 deletions msautotest/wxs/expected/wfs_time_postgis_date_getfeature.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Content-Type: text/xml; subtype="gml/3.2.1"; charset=UTF-8

<?xml version='1.0' encoding="UTF-8" ?>
<wfs:FeatureCollection
xmlns:ms="http://mapserver.gis.umn.edu/mapserver"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:wfs="http://www.opengis.net/wfs/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?myparam=something&amp;SERVICE=WFS&amp;VERSION=2.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=date&amp;OUTPUTFORMAT=application%2Fgml%2Bxml%3B%20version%3D3.2 http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd"
timeStamp="" numberMatched="unknown" numberReturned="1"
next="http://localhost/path/to/wfs_simple?myparam=something&amp;SERVICE=WFS&amp;VERSION=2.0.0&amp;REQUEST=GetFeature&amp;TYPENAMES=date&amp;MAXFEATURES=1&amp;STARTINDEX=1">
<wfs:boundedBy>
<gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326">
<gml:lowerCorner>37.98000 -130.00000</gml:lowerCorner>
<gml:upperCorner>37.98000 -130.00000</gml:upperCorner>
</gml:Envelope>
</wfs:boundedBy>
<wfs:member>
<ms:date gml:id="date.1">
<gml:boundedBy>
<gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326">
<gml:lowerCorner>37.98000 -130.00000</gml:lowerCorner>
<gml:upperCorner>37.98000 -130.00000</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<ms:msGeometry>
<gml:Point gml:id="date.1.1" srsName="urn:ogc:def:crs:EPSG::4326">
<gml:pos>37.98000 -130.00000</gml:pos>
</gml:Point>
</ms:msGeometry>
<ms:date gml:id="date.1.date"><gml:timePosition>2004-01-01</gml:timePosition></ms:date>
</ms:date>
</wfs:member>
</wfs:FeatureCollection>

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ Content-Type: text/xml; subtype=gml/3.1.1; charset=UTF-8
xmlns:wfs="http://www.opengis.net/wfs"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?myparam=something&amp;SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=time&amp;OUTPUTFORMAT=text/xml;%20subtype=gml/3.1.1 http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" timeStamp="" numberOfFeatures="6">
xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?myparam=something&amp;SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=datetime&amp;OUTPUTFORMAT=text/xml;%20subtype=gml/3.1.1 http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" timeStamp="" numberOfFeatures="6">
</wfs:FeatureCollection>

Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ Content-Type: application/gml+xml; version=3.2; charset=UTF-8
<import namespace="http://www.opengis.net/gml/3.2"
schemaLocation="http://schemas.opengis.net/gml/3.2.1/gml.xsd" />

<element name="time"
type="ms:timeType"
<element name="datetime"
type="ms:datetimeType"
substitutionGroup="gml:AbstractFeature" />

<complexType name="timeType">
<complexType name="datetimeType">
<complexContent>
<extension base="gml:AbstractFeatureType">
<sequence>
<element name="msGeometry" type="gml:GeometryPropertyType" minOccurs="0" maxOccurs="1"/>
<element name="gid" minOccurs="0" type="string"/>
<element name="time" minOccurs="0" type="gml:TimeInstantType"/>
<element name="gid" minOccurs="0" type="integer"/>
<element name="datetime" minOccurs="0" type="gml:TimeInstantType"/>
</sequence>
</extension>
</complexContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Content-Type: text/xml; subtype="gml/3.2.1"; charset=UTF-8
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:wfs="http://www.opengis.net/wfs/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?myparam=something&amp;SERVICE=WFS&amp;VERSION=2.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=time&amp;OUTPUTFORMAT=application%2Fgml%2Bxml%3B%20version%3D3.2 http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd"
xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?myparam=something&amp;SERVICE=WFS&amp;VERSION=2.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=datetime&amp;OUTPUTFORMAT=application%2Fgml%2Bxml%3B%20version%3D3.2 http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd"
timeStamp="" numberMatched="1" numberReturned="0">
</wfs:FeatureCollection>

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Content-Type: text/xml; subtype="gml/3.2.1"; charset=UTF-8
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:wfs="http://www.opengis.net/wfs/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?myparam=something&amp;SERVICE=WFS&amp;VERSION=2.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=time&amp;OUTPUTFORMAT=application%2Fgml%2Bxml%3B%20version%3D3.2 http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd"
xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?myparam=something&amp;SERVICE=WFS&amp;VERSION=2.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=datetime&amp;OUTPUTFORMAT=application%2Fgml%2Bxml%3B%20version%3D3.2 http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd"
timeStamp="" numberMatched="6" numberReturned="0">
</wfs:FeatureCollection>

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Content-Type: text/xml; subtype="gml/3.2.1"; charset=UTF-8
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:wfs="http://www.opengis.net/wfs/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?myparam=something&amp;SERVICE=WFS&amp;VERSION=2.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=time&amp;OUTPUTFORMAT=application%2Fgml%2Bxml%3B%20version%3D3.2 http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd"
xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?myparam=something&amp;SERVICE=WFS&amp;VERSION=2.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=datetime&amp;OUTPUTFORMAT=application%2Fgml%2Bxml%3B%20version%3D3.2 http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd"
timeStamp="" numberMatched="0" numberReturned="0">
</wfs:FeatureCollection>

Loading

0 comments on commit e91a4e5

Please sign in to comment.