Permalink
Browse files

Transfer geometries in binary from Postgres (#5238)

see also #5226

Use a trick to have the other fields (when any) still transfered in
text form.
  • Loading branch information...
pvalsecc authored and tbonfort committed Dec 11, 2015
1 parent 4dd30cd commit f6c862eb078bd13010cba20b0f176c2760d30e02
Showing with 29 additions and 7 deletions.
  1. +27 −5 mappostgis.c
  2. +2 −2 mappostgis.h
@@ -81,6 +81,12 @@
#define HAS_Z 0x1
#define HAS_M 0x2

#if TRANSFER_ENCODING == 256
#define RESULTSET_TYPE 1
#else
#define RESULTSET_TYPE 0
#endif

#ifdef USE_POSTGIS


@@ -1731,6 +1737,8 @@ char *msPostGISBuildSQLItems(layerObj *layer)
char *force2d = "";
#if TRANSFER_ENCODING == 64
const char *strGeomTemplate = "encode(ST_AsBinary(%s(\"%s\"),'%s'),'base64') as geom,\"%s\"";
#elif TRANSFER_ENCODING == 256
const char *strGeomTemplate = "ST_AsBinary(%s(\"%s\"),'%s') as geom,\"%s\"::text";
#else
const char *strGeomTemplate = "encode(ST_AsBinary(%s(\"%s\"),'%s'),'hex') as geom,\"%s\"";
#endif
@@ -1745,6 +1753,8 @@ char *msPostGISBuildSQLItems(layerObj *layer)
/* Use AsEWKB() to get 3D */
#if TRANSFER_ENCODING == 64
strGeomTemplate = "encode(AsEWKB(%s(\"%s\"),'%s'),'base64') as geom,\"%s\"";
#elif TRANSFER_ENCODING == 256
strGeomTemplate = "AsEWKB(%s(\"%s\"),'%s') as geom,\"%s\"::text";
#else
strGeomTemplate = "encode(AsEWKB(%s(\"%s\"),'%s'),'hex') as geom,\"%s\"";
#endif
@@ -1771,13 +1781,20 @@ char *msPostGISBuildSQLItems(layerObj *layer)
int t;
for ( t = 0; t < layer->numitems; t++ ) {
length += strlen(layer->items[t]) + 3; /* itemname + "", */
#if TRANSFER_ENCODING == 256
length +=6; /*add a ::text*/
#endif
}
strItems = (char*)msSmallMalloc(length);
strItems[0] = '\0';
for ( t = 0; t < layer->numitems; t++ ) {
strlcat(strItems, "\"", length);
strlcat(strItems, layer->items[t], length);
#if TRANSFER_ENCODING == 256
strlcat(strItems, "\"::text,", length);
#else
strlcat(strItems, "\",", length);
#endif
}
strlcat(strItems, strGeom, length);
}
@@ -2303,7 +2320,7 @@ int msPostGISReadShape(layerObj *layer, shapeObj *shape)
wkbstrlen = PQgetlength(layerinfo->pgresult, layerinfo->rownum, layer->numitems);

if ( ! wkbstr ) {
msSetError(MS_QUERYERR, "Base64 WKB returned is null!", "msPostGISReadShape()");
msSetError(MS_QUERYERR, "WKB returned is null!", "msPostGISReadShape()");
return MS_FAILURE;
}

@@ -2314,8 +2331,14 @@ int msPostGISReadShape(layerObj *layer, shapeObj *shape)
}
#if TRANSFER_ENCODING == 64
result = msPostGISBase64Decode(wkb, wkbstr, wkbstrlen - 1);
w.size = (wkbstrlen - 1)/2;
#elif TRANSFER_ENCODING == 256
result = 1;
memcpy(wkb, wkbstr, wkbstrlen);
w.size = wkbstrlen;
#else
result = msPostGISHexDecode(wkb, wkbstr, wkbstrlen);
w.size = (wkbstrlen - 1)/2;
#endif

if( ! result ) {
@@ -2326,7 +2349,6 @@ int msPostGISReadShape(layerObj *layer, shapeObj *shape)
/* Initialize our wkbObj */
w.wkb = (char*)wkb;
w.ptr = w.wkb;
w.size = (wkbstrlen - 1)/2;

/* Set the type map according to what version of PostGIS we are dealing with */
if( layerinfo->version >= 20000 ) /* PostGIS 2.0+ */
@@ -2786,9 +2808,9 @@ int msPostGISLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery)
// fprintf(stderr, "SQL: %s\n", strSQL);

if(num_bind_values > 0) {
pgresult = PQexecParams(layerinfo->pgconn, strSQL, num_bind_values, NULL, (const char**)layer_bind_values, NULL, NULL, 1);
pgresult = PQexecParams(layerinfo->pgconn, strSQL, num_bind_values, NULL, (const char**)layer_bind_values, NULL, NULL, RESULTSET_TYPE);
} else {
pgresult = PQexecParams(layerinfo->pgconn, strSQL,0, NULL, NULL, NULL, NULL, 0);
pgresult = PQexecParams(layerinfo->pgconn, strSQL,0, NULL, NULL, NULL, NULL, RESULTSET_TYPE);
}

/* free bind values */
@@ -3119,7 +3141,7 @@ int msPostGISLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record)
msDebug("msPostGISLayerGetShape query: %s\n", strSQL);
}

pgresult = PQexecParams(layerinfo->pgconn, strSQL,0, NULL, NULL, NULL, NULL, 0);
pgresult = PQexecParams(layerinfo->pgconn, strSQL,0, NULL, NULL, NULL, NULL, RESULTSET_TYPE);

/* Something went wrong. */
if ( (!pgresult) || (PQresultStatus(pgresult) != PGRES_TUPLES_OK) ) {
@@ -40,8 +40,8 @@
#define BIG_ENDIAN 2
#endif

/* HEX = 16 or BASE64 = 64*/
#define TRANSFER_ENCODING 16
/* HEX = 16, BASE64 = 64, RAW = 256*/
#define TRANSFER_ENCODING 256

/* Substitution token for box hackery */
#define BOXTOKEN "!BOX!"

0 comments on commit f6c862e

Please sign in to comment.