[mapserver-users] GeoJSON OGR output with WFS data type issue

2013-04-11 Thread Kralidis,Tom [Ontario]
Hi: using:

MapServer: 6.2.0
GDAL/OGR: 1.9.2
PostgreSQL: 8.4.13

$ cat /etc/issue
Ubuntu 10.04.4 LTS \n \l

...we have a MapServer setup and configured to feed downstream
applications with (point) observation data via WFS and GeoJSON.

We have an issue where a null value in an integer field is being
returned as a value of 0 in GeoJSON.  This is throwing off applications
who are processing 0 values.  The layer in question is a PostGIS
connection.

Below is a trace along the OGR/MapServer workflow:

PostgreSQL/PostGIS:

FOO=# select postgis_full_version();
 
postgis_full_version


 POSTGIS=2.0.2SVN r10398 GEOS=3.3.5-CAPI-1.7.5 PROJ=Rel. 4.8.0, 6
March 2012 GDAL=GDAL 1.9.2, released 2012/10/08 LIBXML=2.9.0 RASTER
(1 row)

FOO=# \q data_mart_ca_live;

air_temp_qa| integer 
...

FOO=# select air_temp_qa from data_mart_ca_live where
data_payload_id=11177725;
 air_temp_qa
-

(1 row)

Here we see that air_temp_qa (integer value) returns null in SQL.

OGR:

$ ogrinfo -al PG:dbname=FOO host=localhost user=foo password=bar
data_mart_ca_live -where data_payload_id = '11177725'
...
# column definition
air_temp_qa: Integer (0.0)
...
# actual value
air_temp_qa (Integer) = (null)
...
$ ogr2ogr -select air_temp_qa -f GeoJSON foo.json PG:dbname=FOO
host=localhost user=foo password=bar data_mart_ca_live -where
data_payload_id = '11177725'
$ cat foo.json

type: FeatureCollection,

features: [
{ type: Feature, properties: { air_temp: null, air_temp_qa:
null }, geometry: { type: Point, coordinates: [ -111.93,
60.03 ] } }

]
}

So far all is consistent in OGR with what is represented in
PostgreSQL/PostGIS.

MapServer layer definition:

LAYER
 NAME ca-1.0-ascii
 STATUS ON
 DEBUG ON
 CONNECTION dbname=FOO host=localhost user=foo password=bar
 CONNECTIONTYPE POSTGIS
 PROCESSING CLOSE_CONNECTION=DEFER
 DATA the_geom from data_mart_ca_live using unique data_payload_id
using srid=4326
 TYPE POINT
 DUMP TRUE
PROJECTION
  init=epsg:4326
 END
 METADATA
  ows_authorityurl_name taxonomy
  ows_authorityurl_href http://localhost/taxonomy;
  ows_identifier_authority taxonomy
  ows_identifier_value
/msc/observation/atmospheric/surface_weather/ca-1.0-ascii
  wms_layer_group /msc/observation/atmospheric/surface_weather
  ows_title DMS CA obs data with qa
  ows_abstract DMS CA obs data with qa
  ows_keywordlist dms,climate,test,mapserver
  ows_extent -141.089000 36.392987 -52.089000 89.784987 # early out
  wfs_metadataurl_format XML
  gml_include_items all
  gml_types auto
  wms_timeextent 2013-01-11T18:39:34Z/2013-04-11T18:39:34Z
  wms_timeitem instance_datetime
 END
 INCLUDE /home/tomk/msc-ows/trunk/services/msc/classes/dashboard.inc
END

- Test using WMS GetFeatureInfo returns air_temp_qa as an empty XML
element (which is expected/desired).

- Test using WFS GetFeature with default OUTPUTFORMAT:

$  GET
http://localhost/msc-ows?service=WFSversion=1.1.0request=GetFeaturet
ypename=ca-1.0-asciifilter=ogc:Filterogc:PropertyIsEqualToogc:Prop
ertyNamedata_payload_id/ogc:PropertyNameogc:Literal11177725/ogc:Li
teral/ogc:PropertyIsEqualTo/ogc:Filter

... returns air_temp_qa as an empty XML element (which is
expected/desired).

- Test using WFS GetFeature with OUTPUTFORMAT=GeoJSON:

$ GET
http://localhost/msc-ows?service=WFSversion=1.1.0request=GetFeaturet
ypename=ca-1.0-asciifilter=ogc:Filterogc:PropertyIsEqualToogc:Prop
ertyNamedata_payload_id/ogc:PropertyNameogc:Literal11177725/ogc:Li
teral/ogc:PropertyIsEqualTo/ogc:Filteroutputformat=GeoJSON

...returns air_temp_qa in GeoJSON with a value of 0 (i.e. air_temp_qa:
0).

So it looks like, somewhere in MapServer, a null integer value is being
cast to 0.  What's weird is that this is happening only for OGR driver
requested formats, not native MapServer outputs.  But in OGR proper it
works as expected.

Other notes:

- LAYER.METADATA includes gml_types auto.  When commenting that out,
the value comes back as blank (which is good), but all OGC Filters
(which are perfectly valid, from a wide variety of WFS clients) fail
because it looks like, without this, the client is forced to apply a
cast or quote the ogc:Literal value given the data type.

Any suggestions are valued.

Thanks

..Tom

 



___
mapserver-users mailing list
mapserver-users@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/mapserver-users


Re: [mapserver-users] GeoJSON OGR output with WFS data type issue

2013-04-11 Thread Even Rouault

 Any suggestions are valued.

Try the attached patch (only compile tested by me).

I'm unsure if null values are well represented by empty strings by MapServer 
in the shape-values array, but I think so from my quick inspection of the 
code (that's maybe unfortunate that there's no distinction between unset/null 
fields and empty strings)

Ultimately OGR_F_SetFieldString could ignore empty string passed for setting 
numeric fields, but that's probably the job of the client to *not* call 
SetFieldString when it doesn't intent to set a value.

 
 Thanks
 
 ..Tom
 
 
 
 
 
 ___
 mapserver-users mailing list
 mapserver-users@lists.osgeo.org
 http://lists.osgeo.org/mailman/listinfo/mapserver-users
diff --git a/mapogroutput.c b/mapogroutput.c
index 0ee8692..db32c3e 100644
--- a/mapogroutput.c
+++ b/mapogroutput.c
@@ -205,8 +205,10 @@ static int msOGRWriteShape( layerObj *map_layer, OGRLayerH hOGRLayer,
   OGRErr eErr;
   int i, out_field;
   OGRwkbGeometryType eLayerGType, eFeatureGType = wkbUnknown;
+  OGRFeatureDefnH hLayerDefn;
 
-  eLayerGType = OGR_FD_GetGeomType(OGR_L_GetLayerDefn(hOGRLayer));
+  hLayerDefn = OGR_L_GetLayerDefn( hOGRLayer );
+  eLayerGType = OGR_FD_GetGeomType(hLayerDefn);
 
   /*  */
   /*  Transform point geometry.   */
@@ -380,7 +382,7 @@ static int msOGRWriteShape( layerObj *map_layer, OGRLayerH hOGRLayer,
   /*  doesn't match the layer.*/
   /*  */
   eLayerGType =
-wkbFlatten(OGR_FD_GetGeomType(OGR_L_GetLayerDefn(hOGRLayer)));
+wkbFlatten(OGR_FD_GetGeomType(hLayerDefn));
 
   if( hGeom != NULL )
 eFeatureGType = wkbFlatten(OGR_G_GetGeometryType( hGeom ));
@@ -413,7 +415,7 @@ static int msOGRWriteShape( layerObj *map_layer, OGRLayerH hOGRLayer,
   /*  Consider flattening the geometry to 2D if we want 2D*/
   /*  output. */
   /*  */
-  eLayerGType = OGR_FD_GetGeomType(OGR_L_GetLayerDefn(hOGRLayer));
+  eLayerGType = OGR_FD_GetGeomType(hLayerDefn);
 
   if( hGeom != NULL )
 eFeatureGType = OGR_G_GetGeometryType( hGeom );
@@ -426,7 +428,7 @@ static int msOGRWriteShape( layerObj *map_layer, OGRLayerH hOGRLayer,
   /*  */
   /*  Create the feature, and attach the geometry.*/
   /*  */
-  hFeat = OGR_F_Create( OGR_L_GetLayerDefn( hOGRLayer ) );
+  hFeat = OGR_F_Create( hLayerDefn );
 
   OGR_F_SetGeometryDirectly( hFeat, hGeom );
 
@@ -440,6 +442,18 @@ static int msOGRWriteShape( layerObj *map_layer, OGRLayerH hOGRLayer,
 if( !item-visible )
   continue;
 
+/* Avoid setting empty strings for numeric fields, so that OGR */
+/* doesn't take them as 0. */
+if( shape-values[i][0] == '\0' ) {
+  OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn(hLayerDefn, out_field);
+  OGRFieldType eFieldType = OGR_Fld_GetType(hFieldDefn);
+  if( eFieldType == OFTInteger || eFieldType == OFTReal )
+  {
+out_field++;
+continue;
+  }
+}
+
 OGR_F_SetFieldString( hFeat, out_field++, shape-values[i] );
   }
 
___
mapserver-users mailing list
mapserver-users@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/mapserver-users


Re: [mapserver-users] GeoJSON OGR output with WFS data type issue

2013-04-11 Thread Kralidis,Tom [Ontario]

 -Original Message-
 From: Even Rouault [mailto:even.roua...@mines-paris.org]
 Sent: Thursday, April 11, 2013 15:33
 To: mapserver-users@lists.osgeo.org
 Cc: Kralidis,Tom [Ontario]
 Subject: Re: [mapserver-users] GeoJSON OGR output with WFS data type
 issue
 
 
  Any suggestions are valued.
 
 Try the attached patch (only compile tested by me).
 
 I'm unsure if null values are well represented by empty strings by
MapServer
 in the shape-values array, but I think so from my quick inspection of
the
 code (that's maybe unfortunate that there's no distinction between
 unset/null
 fields and empty strings)
 
 Ultimately OGR_F_SetFieldString could ignore empty string passed for
 setting
 numeric fields, but that's probably the job of the client to *not*
call
 SetFieldString when it doesn't intent to set a value.
 

Even: thanks for this.  Works as expected.

Thanks

..Tom



___
mapserver-users mailing list
mapserver-users@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/mapserver-users