[postgis-tickets] r17651 - Handle POINT EMPTY in shape loader/dumper
Paul Ramsey
pramsey at cleverelephant.ca
Wed Jul 31 02:41:58 PDT 2019
Author: pramsey
Date: 2019-07-31 14:41:58 -0700 (Wed, 31 Jul 2019)
New Revision: 17651
Modified:
branches/2.4/NEWS
branches/2.4/loader/pgsql2shp-core.c
branches/2.4/loader/shp2pgsql-core.c
Log:
Handle POINT EMPTY in shape loader/dumper
References #4437
Modified: branches/2.4/NEWS
===================================================================
--- branches/2.4/NEWS 2019-07-31 21:41:51 UTC (rev 17650)
+++ branches/2.4/NEWS 2019-07-31 21:41:58 UTC (rev 17651)
@@ -13,6 +13,7 @@
- #4466, Fix undefined behaviour in _postgis_gserialized_stats (Raúl Marín)
- #4209, Handle NULL geometry values in pgsql2shp (Paul Ramsey)
- #4419, Use protobuf version to enable/disable mvt/geobuf (Paul Ramsey)
+ - #4437, Handle POINT EMPTY in shape loader/dumper (Paul Ramsey)
PostGIS 2.4.7
Modified: branches/2.4/loader/pgsql2shp-core.c
===================================================================
--- branches/2.4/loader/pgsql2shp-core.c 2019-07-31 21:41:51 UTC (rev 17650)
+++ branches/2.4/loader/pgsql2shp-core.c 2019-07-31 21:41:58 UTC (rev 17651)
@@ -67,7 +67,18 @@
/** @brief Binary to hexewkb conversion function */
char *convert_bytes_to_hex(uint8_t *ewkb, size_t size);
+static SHPObject *
+create_point_empty(SHPDUMPERSTATE *state, LWPOINT *lwpoint)
+{
+ SHPObject *obj;
+ const uint8_t ndr_nan[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f};
+ double double_nan;
+ memcpy(&double_nan, ndr_nan, 8);
+ obj = SHPCreateObject(state->outshptype, -1, 0, NULL, NULL, 1, &double_nan, &double_nan, &double_nan, &double_nan);
+ return obj;
+}
+
static SHPObject *
create_point(SHPDUMPERSTATE *state, LWPOINT *lwpoint)
{
@@ -2108,7 +2119,14 @@
switch (lwgeom->type)
{
case POINTTYPE:
- obj = create_point(state, lwgeom_as_lwpoint(lwgeom));
+ if (lwgeom_is_empty(lwgeom))
+ {
+ obj = create_point_empty(state, lwgeom_as_lwpoint(lwgeom));
+ }
+ else
+ {
+ obj = create_point(state, lwgeom_as_lwpoint(lwgeom));
+ }
break;
case MULTIPOINTTYPE:
Modified: branches/2.4/loader/shp2pgsql-core.c
===================================================================
--- branches/2.4/loader/shp2pgsql-core.c 2019-07-31 21:41:51 UTC (rev 17650)
+++ branches/2.4/loader/shp2pgsql-core.c 2019-07-31 21:41:58 UTC (rev 17651)
@@ -240,42 +240,51 @@
FLAGS_SET_Z(dims, state->has_z);
FLAGS_SET_M(dims, state->has_m);
- /* Allocate memory for our array of LWPOINTs and our dynptarrays */
- lwmultipoints = malloc(sizeof(LWPOINT *) * obj->nVertices);
-
- /* We need an array of pointers to each of our sub-geometries */
- for (u = 0; u < obj->nVertices; u++)
+ /* POINT EMPTY encoded as POINT(NaN NaN) */
+ if (obj->nVertices == 1 && isnan(obj->padfX[0]) && isnan(obj->padfY[0]))
{
- /* Create a ptarray containing a single point */
- POINTARRAY *pa = ptarray_construct_empty(state->has_z, state->has_m, 1);
+ lwgeom = lwpoint_as_lwgeom(lwpoint_construct_empty(state->from_srid, state->has_z, state->has_m));
+ }
+ /* Not empty */
+ else
+ {
+ /* Allocate memory for our array of LWPOINTs and our dynptarrays */
+ lwmultipoints = malloc(sizeof(LWPOINT *) * obj->nVertices);
- /* Generate the point */
- point4d.x = obj->padfX[u];
- point4d.y = obj->padfY[u];
+ /* We need an array of pointers to each of our sub-geometries */
+ for (u = 0; u < obj->nVertices; u++)
+ {
+ /* Create a ptarray containing a single point */
+ POINTARRAY *pa = ptarray_construct_empty(state->has_z, state->has_m, 1);
- if (state->has_z)
- point4d.z = obj->padfZ[u];
- if (state->has_m)
- point4d.m = obj->padfM[u];
+ /* Generate the point */
+ point4d.x = obj->padfX[u];
+ point4d.y = obj->padfY[u];
- /* Add in the point! */
- ptarray_append_point(pa, &point4d, LW_TRUE);
+ if (state->has_z)
+ point4d.z = obj->padfZ[u];
+ if (state->has_m)
+ point4d.m = obj->padfM[u];
- /* Generate the LWPOINT */
- lwmultipoints[u] = lwpoint_as_lwgeom(lwpoint_construct(state->from_srid, NULL, pa));
- }
+ /* Add in the point! */
+ ptarray_append_point(pa, &point4d, LW_TRUE);
- /* If we have more than 1 vertex then we are working on a MULTIPOINT and so generate a MULTIPOINT
- rather than a POINT */
- if ((obj->nVertices > 1) || force_multi)
- {
- lwgeom = lwcollection_as_lwgeom(lwcollection_construct(MULTIPOINTTYPE, state->from_srid, NULL, obj->nVertices, lwmultipoints));
+ /* Generate the LWPOINT */
+ lwmultipoints[u] = lwpoint_as_lwgeom(lwpoint_construct(state->from_srid, NULL, pa));
+ }
+
+ /* If we have more than 1 vertex then we are working on a MULTIPOINT and so generate a MULTIPOINT
+ rather than a POINT */
+ if ((obj->nVertices > 1) || force_multi)
+ {
+ lwgeom = lwcollection_as_lwgeom(lwcollection_construct(MULTIPOINTTYPE, state->from_srid, NULL, obj->nVertices, lwmultipoints));
+ }
+ else
+ {
+ lwgeom = lwmultipoints[0];
+ lwfree(lwmultipoints);
+ }
}
- else
- {
- lwgeom = lwmultipoints[0];
- lwfree(lwmultipoints);
- }
if (state->config->use_wkt)
{
More information about the postgis-tickets
mailing list