From: Paul Ramsey Date: Wed, 31 Jul 2019 21:41:51 +0000 (+0000) Subject: Handle POINT EMPTY in shape loader/dumper X-Git-Tag: 2.3.10~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1e9f797dc4e72417dfa1b561b2248c91887242f6;p=postgis Handle POINT EMPTY in shape loader/dumper References #4437 git-svn-id: http://svn.osgeo.org/postgis/branches/2.3@17650 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/NEWS b/NEWS index 879cacde5..c69de63f2 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,7 @@ PostGIS 2.3.10 - #4406, Throw on invalid characters when decoding geohash (Raúl Marín) - #4466, Fix undefined behaviour in _postgis_gserialized_stats (Raúl Marín) - #4209, Handle NULL geometry values in pgsql2shp (Paul Ramsey) + - #4437, Handle POINT EMPTY in shape loader/dumper (Paul Ramsey) PostGIS 2.3.9 diff --git a/loader/pgsql2shp-core.c b/loader/pgsql2shp-core.c index 3027edb65..ecd9b537c 100644 --- a/loader/pgsql2shp-core.c +++ b/loader/pgsql2shp-core.c @@ -67,6 +67,17 @@ static char * goodDBFValue(char *in, char fieldType); /** @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 @@ int ShpLoaderGenerateShapeRow(SHPDUMPERSTATE *state) 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: diff --git a/loader/shp2pgsql-core.c b/loader/shp2pgsql-core.c index 23a39e7c9..b91c8e3f2 100644 --- a/loader/shp2pgsql-core.c +++ b/loader/shp2pgsql-core.c @@ -240,41 +240,50 @@ GeneratePointGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometry, in 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])) + { + lwgeom = lwpoint_as_lwgeom(lwpoint_construct_empty(state->from_srid, state->has_z, state->has_m)); + } + /* Not empty */ + else { - /* Create a ptarray containing a single point */ - POINTARRAY *pa = ptarray_construct_empty(state->has_z, state->has_m, 1); + /* 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)); - } - else - { - lwgeom = lwmultipoints[0]; - lwfree(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); + } } if (state->config->use_wkt)