Allow empty geometry to round-trip JSON format, references #4895

This commit is contained in:
Paul Ramsey 2021-07-30 12:34:59 -07:00
parent 320a7b548f
commit b4e803db05
4 changed files with 79 additions and 18 deletions

View file

@ -40,6 +40,10 @@ static void do_geojson_test(const char * exp, char * in, char * exp_srs)
fprintf(stderr, "\nIn: %s\nExp: %s\nObt: %s\n", in, exp, h);
CU_ASSERT_STRING_EQUAL(h, exp);
}
else
{
CU_ASSERT_STRING_EQUAL(h, exp);
}
if ( exp_srs )
{
@ -199,6 +203,36 @@ static void in_geojson_test_geoms(void)
"GEOMETRYCOLLECTION EMPTY",
"{\"type\":\"GeometryCollection\",\"geometries\":[]}",
NULL);
/* Empty Point */
do_geojson_test(
"POINT EMPTY",
"{\"type\":\"Point\",\"coordinates\":[]}",
NULL);
/* Empty LineString */
do_geojson_test(
"LINESTRING EMPTY",
"{\"type\":\"LineString\",\"coordinates\":[]}",
NULL);
/* Empty Polygon */
do_geojson_test(
"POLYGON EMPTY",
"{\"type\":\"Polygon\",\"coordinates\":[]}",
NULL);
/* Empty MultiPoint */
do_geojson_test(
"MULTIPOINT EMPTY",
"{\"type\":\"MultiPoint\",\"coordinates\":[]}",
NULL);
/* Empty MultiPolygon */
do_geojson_test(
"MULTIPOLYGON EMPTY",
"{\"type\":\"MultiPolygon\",\"coordinates\":[]}",
NULL);
}
/*

View file

@ -111,6 +111,8 @@ parse_geojson_coord(json_object *poObj, int *hasz, POINTARRAY *pa)
{
json_object *poObjCoord = NULL;
const int nSize = json_object_array_length(poObj);
if (nSize == 0)
return LW_TRUE;
if (nSize < 2)
{
lwerror("Too few ordinates in GeoJSON");

View file

@ -370,14 +370,17 @@ asgeojson_multipoint_size(const LWMPOINT *mpoint, const char *srs, GBOX *bbox, i
{
LWPOINT * point;
int size;
uint32_t i;
uint32_t i, ngeoms = mpoint->ngeoms;
size = sizeof("{'type':'MultiPoint',");
if (srs) size += asgeojson_srs_size(srs);
if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(mpoint->flags), precision);
size += sizeof("'coordinates':[]}");
for (i=0; i<mpoint->ngeoms; i++)
if (lwgeom_is_empty((LWGEOM*)mpoint))
ngeoms = 0;
for (i=0; i<ngeoms; i++)
{
point = mpoint->geoms[i];
size += pointArray_geojson_size(point->point, precision);
@ -391,7 +394,7 @@ static size_t
asgeojson_multipoint_buf(const LWMPOINT *mpoint, const char *srs, char *output, GBOX *bbox, int precision)
{
LWPOINT *point;
uint32_t i;
uint32_t i, ngeoms = mpoint->ngeoms;
char *ptr=output;
ptr += sprintf(ptr, "{\"type\":\"MultiPoint\",");
@ -399,7 +402,10 @@ asgeojson_multipoint_buf(const LWMPOINT *mpoint, const char *srs, char *output,
if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(mpoint->flags), precision);
ptr += sprintf(ptr, "\"coordinates\":[");
for (i=0; i<mpoint->ngeoms; i++)
if (lwgeom_is_empty((LWGEOM*)mpoint))
ngeoms = 0;
for (i=0; i<ngeoms; i++)
{
if (i) ptr += sprintf(ptr, ",");
point = mpoint->geoms[i];
@ -431,14 +437,17 @@ asgeojson_multiline_size(const LWMLINE *mline, const char *srs, GBOX *bbox, int
{
LWLINE * line;
int size;
uint32_t i;
uint32_t i, ngeoms = mline->ngeoms;
size = sizeof("{'type':'MultiLineString',");
if (srs) size += asgeojson_srs_size(srs);
if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(mline->flags), precision);
size += sizeof("'coordinates':[]}");
for (i=0 ; i<mline->ngeoms; i++)
if (lwgeom_is_empty((LWGEOM*)mline))
ngeoms = 0;
for (i=0 ; i<ngeoms; i++)
{
line = mline->geoms[i];
size += pointArray_geojson_size(line->points, precision);
@ -453,7 +462,7 @@ static size_t
asgeojson_multiline_buf(const LWMLINE *mline, const char *srs, char *output, GBOX *bbox, int precision)
{
LWLINE *line;
uint32_t i;
uint32_t i, ngeoms = mline->ngeoms;
char *ptr=output;
ptr += sprintf(ptr, "{\"type\":\"MultiLineString\",");
@ -461,7 +470,10 @@ asgeojson_multiline_buf(const LWMLINE *mline, const char *srs, char *output, GBO
if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(mline->flags), precision);
ptr += sprintf(ptr, "\"coordinates\":[");
for (i=0; i<mline->ngeoms; i++)
if (lwgeom_is_empty((LWGEOM*)mline))
ngeoms = 0;
for (i=0; i<ngeoms; i++)
{
if (i) ptr += sprintf(ptr, ",");
ptr += sprintf(ptr, "[");
@ -496,14 +508,17 @@ asgeojson_multipolygon_size(const LWMPOLY *mpoly, const char *srs, GBOX *bbox, i
{
LWPOLY *poly;
int size;
uint32_t i, j;
uint32_t i, j, ngeoms = mpoly->ngeoms;
size = sizeof("{'type':'MultiPolygon',");
if (srs) size += asgeojson_srs_size(srs);
if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(mpoly->flags), precision);
size += sizeof("'coordinates':[]}");
for (i=0; i < mpoly->ngeoms; i++)
if (lwgeom_is_empty((LWGEOM*)mpoly))
ngeoms = 0;
for (i=0; i < ngeoms; i++)
{
poly = mpoly->geoms[i];
for (j=0 ; j <poly->nrings ; j++)
@ -523,14 +538,18 @@ static size_t
asgeojson_multipolygon_buf(const LWMPOLY *mpoly, const char *srs, char *output, GBOX *bbox, int precision)
{
LWPOLY *poly;
uint32_t i, j;
uint32_t i, j, ngeoms = mpoly->ngeoms;
char *ptr=output;
ptr += sprintf(ptr, "{\"type\":\"MultiPolygon\",");
if (srs) ptr += asgeojson_srs_buf(ptr, srs);
if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(mpoly->flags), precision);
ptr += sprintf(ptr, "\"coordinates\":[");
for (i=0; i<mpoly->ngeoms; i++)
if (lwgeom_is_empty((LWGEOM*)mpoly))
ngeoms = 0;
for (i=0; i < ngeoms; i++)
{
if (i) ptr += sprintf(ptr, ",");
ptr += sprintf(ptr, "[");
@ -568,7 +587,7 @@ asgeojson_multipolygon(const LWMPOLY *mpoly, const char *srs, GBOX *bbox, int pr
static size_t
asgeojson_collection_size(const LWCOLLECTION *col, const char *srs, GBOX *bbox, int precision)
{
uint32_t i;
uint32_t i, ngeoms = col->ngeoms;
size_t size;
LWGEOM *subgeom;
@ -577,7 +596,10 @@ asgeojson_collection_size(const LWCOLLECTION *col, const char *srs, GBOX *bbox,
if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(col->flags), precision);
size += sizeof("'geometries':");
for (i=0; i<col->ngeoms; i++)
if (lwgeom_is_empty((LWGEOM*)col))
ngeoms = 0;
for (i=0; i<ngeoms; i++)
{
subgeom = col->geoms[i];
size += asgeojson_geom_size(subgeom, NULL, precision);
@ -591,7 +613,7 @@ asgeojson_collection_size(const LWCOLLECTION *col, const char *srs, GBOX *bbox,
static size_t
asgeojson_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, GBOX *bbox, int precision)
{
uint32_t i;
uint32_t i, ngeoms = col->ngeoms;
char *ptr=output;
LWGEOM *subgeom;
@ -600,7 +622,10 @@ asgeojson_collection_buf(const LWCOLLECTION *col, const char *srs, char *output,
if (col->ngeoms && bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(col->flags), precision);
ptr += sprintf(ptr, "\"geometries\":[");
for (i=0; i<col->ngeoms; i++)
if (lwgeom_is_empty((LWGEOM*)col))
ngeoms = 0;
for (i=0; i<ngeoms; i++)
{
if (i) ptr += sprintf(ptr, ",");
subgeom = col->geoms[i];

View file

@ -12,8 +12,8 @@ ERROR: Unable to find 'coordinates' in GeoJSON string
ERROR: unexpected character (at offset 0)
ERROR: unexpected end of data (at offset 0)
ERROR: invalid GeoJSON representation
ERROR: Too few ordinates in GeoJSON
ERROR: Too few ordinates in GeoJSON
#1434.5|0101000020E6100000000000000000F87F000000000000F87F
#1434.6|0104000020E610000000000000
ERROR: Unable to find 'coordinates' in GeoJSON string
ERROR: Unable to find 'coordinates' in GeoJSON string
#2130|50