From 97626912370b3622dc49a26b4cef050bdf36661d Mon Sep 17 00:00:00 2001 From: Darafei Praliaskouski Date: Sun, 4 Aug 2019 11:43:42 +0000 Subject: [PATCH] Triangle and TIN output support Make all the "Unsupported geometry type" name themselves by __func__. In case output format doesn't know about TIN/Triangle, output them as GeometryCollection/Polygon. Closes #4399 Closes https://github.com/postgis/postgis/pull/454 git-svn-id: http://svn.osgeo.org/postgis/trunk@17674 b70326c6-7e19-0410-871a-916f4a2858ee --- NEWS | 2 + liblwgeom/lwgeom_median.c | 4 +- liblwgeom/lwin_twkb.c | 4 +- liblwgeom/lwin_wkb.c | 2 +- liblwgeom/lwiterator.c | 4 +- liblwgeom/lwmval.c | 4 +- liblwgeom/lwout_geojson.c | 99 ++++++++++++++++++-------- liblwgeom/lwout_kml.c | 24 +++++++ liblwgeom/lwout_twkb.c | 24 ++++++- liblwgeom/lwout_wkb.c | 7 +- liblwgeom/lwstroke.c | 3 +- liblwgeom/measures.c | 12 ++-- liblwgeom/measures3d.c | 10 +-- postgis/geobuf.c | 22 ++++++ postgis/lwgeom_out_geobuf.c | 6 +- postgis/lwgeom_transform.c | 10 +-- postgis/mvt.c | 3 + regress/core/geometric_median_expected | 2 +- regress/core/out_geometry_expected | 2 +- regress/core/regress_proj_expected | 2 +- regress/core/tickets.sql | 36 ++++++++++ regress/core/tickets_expected | 37 ++++++++++ 22 files changed, 249 insertions(+), 70 deletions(-) diff --git a/NEWS b/NEWS index 455444398..e844188fc 100644 --- a/NEWS +++ b/NEWS @@ -195,6 +195,8 @@ Additional features enabled if you are running Proj6+ and PostgreSQL 12 ones faster. (Darafei Praliaskouski) - #4403, Support for shp2pgsql ability to reproject with copy mode (-D) (Regina Obe) - #4410, More descriptive error messages about SRID mismatch (Darafei Praliaskouski) + - #4399, TIN and Triangle output support in all output functions (Darafei + Praliaskouski) * Fixes * - #4342, Move deprecated functions into legacy.sql file diff --git a/liblwgeom/lwgeom_median.c b/liblwgeom/lwgeom_median.c index 03d37b12c..0ff90f66a 100644 --- a/liblwgeom/lwgeom_median.c +++ b/liblwgeom/lwgeom_median.c @@ -279,14 +279,14 @@ lwmpoint_median(const LWMPOINT* g, double tol, uint32_t max_iter, char fail_if_n LWPOINT* lwgeom_median(const LWGEOM* g, double tol, uint32_t max_iter, char fail_if_not_converged) { - switch( lwgeom_get_type(g) ) + switch (g->type) { case POINTTYPE: return lwpoint_clone(lwgeom_as_lwpoint(g)); case MULTIPOINTTYPE: return lwmpoint_median(lwgeom_as_lwmpoint(g), tol, max_iter, fail_if_not_converged); default: - lwerror("Unsupported geometry type in lwgeom_median"); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(g->type)); return NULL; } } diff --git a/liblwgeom/lwin_twkb.c b/liblwgeom/lwin_twkb.c index 93313188b..445b4a9b0 100644 --- a/liblwgeom/lwin_twkb.c +++ b/liblwgeom/lwin_twkb.c @@ -631,14 +631,12 @@ LWGEOM* lwgeom_from_twkb_state(twkb_parse_state *s) break; /* Unknown type! */ default: - lwerror("Unsupported geometry type: %s [%d]", lwtype_name(s->lwtype), s->lwtype); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(s->lwtype)); break; } if ( has_bbox ) - { geom->bbox = gbox_clone(&bbox); - } return geom; } diff --git a/liblwgeom/lwin_wkb.c b/liblwgeom/lwin_wkb.c index ede85b8b9..46850ba39 100644 --- a/liblwgeom/lwin_wkb.c +++ b/liblwgeom/lwin_wkb.c @@ -745,7 +745,7 @@ LWGEOM* lwgeom_from_wkb_state(wkb_parse_state *s) /* Unknown type! */ default: - lwerror("Unsupported geometry type: %s [%d]", lwtype_name(s->lwtype), s->lwtype); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(s->lwtype)); } /* Return value to keep compiler happy. */ diff --git a/liblwgeom/lwiterator.c b/liblwgeom/lwiterator.c index 55cb0d1a1..a825239a2 100644 --- a/liblwgeom/lwiterator.c +++ b/liblwgeom/lwiterator.c @@ -100,14 +100,12 @@ extract_pointarrays_from_lwgeom(LWGEOM* g) LWPOLY* p = lwgeom_as_lwpoly(g); int i; for (i = p->nrings - 1; i >= 0; i--) - { n = prepend_node(p->rings[i], n); - } return n; } default: - lwerror("Unsupported geometry type for lwpointiterator"); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(g->type)); } return NULL; diff --git a/liblwgeom/lwmval.c b/liblwgeom/lwmval.c index 078080195..6e8f88fb5 100644 --- a/liblwgeom/lwmval.c +++ b/liblwgeom/lwmval.c @@ -212,7 +212,7 @@ static LWGEOM* lwgeom_filter_m_ignore_null(LWGEOM *geom,double min,double max, i } /* Unknown type! */ default: - lwerror("Unsupported geometry type: %s [%d] in function %s", lwtype_name((geom)->type), (geom)->type, __func__); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(geom->type)); } return geom_out; @@ -258,7 +258,7 @@ LWGEOM* lwgeom_filter_m(LWGEOM *geom,double min,double max, int returnm) } /* Unknown type! */ default: - lwerror("Unsupported geometry type: %s [%d] in function %s", lwtype_name((geom)->type), (geom)->type, __func__); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(geom->type)); } } /*Shouldn't be possible*/ diff --git a/liblwgeom/lwout_geojson.c b/liblwgeom/lwout_geojson.c index 90a23787b..36f14a295 100644 --- a/liblwgeom/lwout_geojson.c +++ b/liblwgeom/lwout_geojson.c @@ -30,11 +30,12 @@ static char *asgeojson_point(const LWPOINT *point, char *srs, GBOX *bbox, int precision); static char *asgeojson_line(const LWLINE *line, char *srs, GBOX *bbox, int precision); +static char *asgeojson_triangle(const LWTRIANGLE *tri, char *srs, GBOX *bbox, int precision); static char *asgeojson_poly(const LWPOLY *poly, char *srs, GBOX *bbox, int precision); -static char * asgeojson_multipoint(const LWMPOINT *mpoint, char *srs, GBOX *bbox, int precision); -static char * asgeojson_multiline(const LWMLINE *mline, char *srs, GBOX *bbox, int precision); -static char * asgeojson_multipolygon(const LWMPOLY *mpoly, char *srs, GBOX *bbox, int precision); -static char * asgeojson_collection(const LWCOLLECTION *col, char *srs, GBOX *bbox, int precision); +static char *asgeojson_multipoint(const LWMPOINT *mpoint, char *srs, GBOX *bbox, int precision); +static char *asgeojson_multiline(const LWMLINE *mline, char *srs, GBOX *bbox, int precision); +static char *asgeojson_multipolygon(const LWMPOLY *mpoly, char *srs, GBOX *bbox, int precision); +static char *asgeojson_collection(const LWCOLLECTION *col, char *srs, GBOX *bbox, int precision); static size_t asgeojson_geom_size(const LWGEOM *geom, GBOX *bbox, int precision); static size_t asgeojson_geom_buf(const LWGEOM *geom, char *output, GBOX *bbox, int precision); @@ -75,6 +76,9 @@ lwgeom_to_geojson(const LWGEOM *geom, char *srs, int precision, int has_bbox) return asgeojson_multiline((LWMLINE*)geom, srs, bbox, precision); case MULTIPOLYGONTYPE: return asgeojson_multipolygon((LWMPOLY*)geom, srs, bbox, precision); + case TRIANGLETYPE: + return asgeojson_triangle((LWTRIANGLE *)geom, srs, bbox, precision); + case TINTYPE: case COLLECTIONTYPE: return asgeojson_collection((LWCOLLECTION*)geom, srs, bbox, precision); default: @@ -209,7 +213,55 @@ asgeojson_point(const LWPOINT *point, char *srs, GBOX *bbox, int precision) return output; } +/** + * Triangle Geometry + */ +static size_t +asgeojson_triangle_size(const LWTRIANGLE *tri, char *srs, GBOX *bbox, int precision) +{ + int size; + + size = sizeof("{'type':'Polygon',"); + if (srs) + size += asgeojson_srs_size(srs); + if (bbox) + size += asgeojson_bbox_size(FLAGS_GET_Z(tri->flags), precision); + size += sizeof("'coordinates':[[]]}"); + size += pointArray_geojson_size(tri->points, precision); + + return size; +} + +static size_t +asgeojson_triangle_buf(const LWTRIANGLE *tri, char *srs, char *output, GBOX *bbox, int precision) +{ + char *ptr = output; + + ptr += sprintf(ptr, "{\"type\":\"Polygon\","); + if (srs) + ptr += asgeojson_srs_buf(ptr, srs); + if (bbox) + ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(tri->flags), precision); + ptr += sprintf(ptr, "\"coordinates\":[["); + ptr += pointArray_to_geojson(tri->points, ptr, precision); + ptr += sprintf(ptr, "]]}"); + + return (ptr - output); +} + +static char * +asgeojson_triangle(const LWTRIANGLE *tri, char *srs, GBOX *bbox, int precision) +{ + char *output; + int size; + + size = asgeojson_triangle_size(tri, srs, bbox, precision); + output = lwalloc(size); + asgeojson_triangle_buf(tri, srs, output, bbox, precision); + + return output; +} /** * Line Geometry @@ -288,6 +340,7 @@ static size_t asgeojson_poly_buf(const LWPOLY *poly, char *srs, char *output, GBOX *bbox, int precision) { uint32_t i; + char *ptr=output; ptr += sprintf(ptr, "{\"type\":\"Polygon\","); @@ -599,40 +652,26 @@ asgeojson_collection(const LWCOLLECTION *col, char *srs, GBOX *bbox, int precisi static size_t asgeojson_geom_size(const LWGEOM *geom, GBOX *bbox, int precision) { - int type = geom->type; - size_t size = 0; - - switch (type) + switch (geom->type) { case POINTTYPE: - size = asgeojson_point_size((LWPOINT*)geom, NULL, bbox, precision); - break; - + return asgeojson_point_size((LWPOINT *)geom, NULL, bbox, precision); case LINETYPE: - size = asgeojson_line_size((LWLINE*)geom, NULL, bbox, precision); - break; - + return asgeojson_line_size((LWLINE *)geom, NULL, bbox, precision); + case TRIANGLETYPE: + return asgeojson_triangle_size((LWTRIANGLE *)geom, NULL, bbox, precision); case POLYGONTYPE: - size = asgeojson_poly_size((LWPOLY*)geom, NULL, bbox, precision); - break; - + return asgeojson_poly_size((LWPOLY *)geom, NULL, bbox, precision); case MULTIPOINTTYPE: - size = asgeojson_multipoint_size((LWMPOINT*)geom, NULL, bbox, precision); - break; - + return asgeojson_multipoint_size((LWMPOINT *)geom, NULL, bbox, precision); case MULTILINETYPE: - size = asgeojson_multiline_size((LWMLINE*)geom, NULL, bbox, precision); - break; - + return asgeojson_multiline_size((LWMLINE *)geom, NULL, bbox, precision); case MULTIPOLYGONTYPE: - size = asgeojson_multipolygon_size((LWMPOLY*)geom, NULL, bbox, precision); - break; - + return asgeojson_multipolygon_size((LWMPOLY *)geom, NULL, bbox, precision); default: lwerror("GeoJson: geometry not supported."); + return 0; } - - return size; } @@ -656,6 +695,10 @@ asgeojson_geom_buf(const LWGEOM *geom, char *output, GBOX *bbox, int precision) ptr += asgeojson_poly_buf((LWPOLY*)geom, NULL, ptr, bbox, precision); break; + case TRIANGLETYPE: + ptr += asgeojson_triangle_buf((LWTRIANGLE *)geom, NULL, ptr, bbox, precision); + break; + case MULTIPOINTTYPE: ptr += asgeojson_multipoint_buf((LWMPOINT*)geom, NULL, ptr, bbox, precision); break; diff --git a/liblwgeom/lwout_kml.c b/liblwgeom/lwout_kml.c index fa8912df1..231c8b4e1 100644 --- a/liblwgeom/lwout_kml.c +++ b/liblwgeom/lwout_kml.c @@ -30,6 +30,7 @@ static int lwgeom_to_kml2_sb(const LWGEOM *geom, int precision, const char *prefix, stringbuffer_t *sb); static int lwpoint_to_kml2_sb(const LWPOINT *point, int precision, const char *prefix, stringbuffer_t *sb); static int lwline_to_kml2_sb(const LWLINE *line, int precision, const char *prefix, stringbuffer_t *sb); +static int lwtriangle_to_kml2_sb(const LWTRIANGLE *tri, int precision, const char *prefix, stringbuffer_t *sb); static int lwpoly_to_kml2_sb(const LWPOLY *poly, int precision, const char *prefix, stringbuffer_t *sb); static int lwcollection_to_kml2_sb(const LWCOLLECTION *col, int precision, const char *prefix, stringbuffer_t *sb); static int ptarray_to_kml2_sb(const POINTARRAY *pa, int precision, stringbuffer_t *sb); @@ -76,12 +77,16 @@ lwgeom_to_kml2_sb(const LWGEOM *geom, int precision, const char *prefix, stringb case LINETYPE: return lwline_to_kml2_sb((LWLINE*)geom, precision, prefix, sb); + case TRIANGLETYPE: + return lwtriangle_to_kml2_sb((LWTRIANGLE *)geom, precision, prefix, sb); + case POLYGONTYPE: return lwpoly_to_kml2_sb((LWPOLY*)geom, precision, prefix, sb); case MULTIPOINTTYPE: case MULTILINETYPE: case MULTIPOLYGONTYPE: + case TINTYPE: return lwcollection_to_kml2_sb((LWCOLLECTION*)geom, precision, prefix, sb); default: @@ -146,6 +151,25 @@ lwline_to_kml2_sb(const LWLINE *line, int precision, const char *prefix, stringb return LW_SUCCESS; } +static int +lwtriangle_to_kml2_sb(const LWTRIANGLE *tri, int precision, const char *prefix, stringbuffer_t *sb) +{ + /* Open polygon */ + if (stringbuffer_aprintf( + sb, "<%sPolygon><%souterBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix, prefix) < 0) + return LW_FAILURE; + /* Coordinate array */ + if (ptarray_to_kml2_sb(tri->points, precision, sb) == LW_FAILURE) + return LW_FAILURE; + /* Close polygon */ + if (stringbuffer_aprintf( + sb, "", prefix, prefix, prefix, prefix) < + 0) + return LW_FAILURE; + + return LW_SUCCESS; +} + static int lwpoly_to_kml2_sb(const LWPOLY *poly, int precision, const char *prefix, stringbuffer_t *sb) { diff --git a/liblwgeom/lwout_twkb.c b/liblwgeom/lwout_twkb.c index 0286ab55e..e87a72c8e 100644 --- a/liblwgeom/lwout_twkb.c +++ b/liblwgeom/lwout_twkb.c @@ -42,6 +42,7 @@ static uint8_t lwgeom_twkb_type(const LWGEOM *geom) case LINETYPE: twkb_type = WKB_LINESTRING_TYPE; break; + case TRIANGLETYPE: case POLYGONTYPE: twkb_type = WKB_POLYGON_TYPE; break; @@ -54,12 +55,12 @@ static uint8_t lwgeom_twkb_type(const LWGEOM *geom) case MULTIPOLYGONTYPE: twkb_type = WKB_MULTIPOLYGON_TYPE; break; + case TINTYPE: case COLLECTIONTYPE: twkb_type = WKB_GEOMETRYCOLLECTION_TYPE; break; default: - lwerror("Unsupported geometry type: %s [%d]", - lwtype_name(geom->type), geom->type); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(geom->type)); } return twkb_type; } @@ -254,6 +255,17 @@ static int lwline_to_twkb_buf(const LWLINE *line, TWKB_GLOBALS *globals, TWKB_ST return 0; } +static int +lwtriangle_to_twkb_buf(const LWTRIANGLE *tri, TWKB_GLOBALS *globals, TWKB_STATE *ts) +{ + LWDEBUGF(2, "Entered %s", __func__); + bytebuffer_append_uvarint(ts->geom_buf, (uint64_t)1); + + /* Set the coordinates (do write npoints) */ + ptarray_to_twkb_buf(tri->points, globals, ts, 1, 2); + return 0; +} + /****************************************************************** * POLYGONS *******************************************************************/ @@ -379,6 +391,11 @@ static int lwgeom_to_twkb_buf(const LWGEOM *geom, TWKB_GLOBALS *globals, TWKB_ST LWDEBUGF(4,"Type found is Linestring, %d", geom->type); return lwline_to_twkb_buf((LWLINE*) geom, globals, ts); } + case TRIANGLETYPE: + { + LWDEBUGF(4, "Type found is Triangle, %d", geom->type); + return lwtriangle_to_twkb_buf((LWTRIANGLE *)geom, globals, ts); + } /* Polygon has 'nrings' and 'rings' elements */ case POLYGONTYPE: { @@ -395,13 +412,14 @@ static int lwgeom_to_twkb_buf(const LWGEOM *geom, TWKB_GLOBALS *globals, TWKB_ST return lwmulti_to_twkb_buf((LWCOLLECTION*)geom, globals, ts); } case COLLECTIONTYPE: + case TINTYPE: { LWDEBUGF(4,"Type found is collection, %d", geom->type); return lwcollection_to_twkb_buf((LWCOLLECTION*) geom, globals, ts); } /* Unknown type! */ default: - lwerror("Unsupported geometry type: %s [%d]", lwtype_name((geom)->type), (geom)->type); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(geom->type)); } return 0; diff --git a/liblwgeom/lwout_wkb.c b/liblwgeom/lwout_wkb.c index 803079230..0ba78d6aa 100644 --- a/liblwgeom/lwout_wkb.c +++ b/liblwgeom/lwout_wkb.c @@ -131,8 +131,7 @@ static uint32_t lwgeom_wkb_type(const LWGEOM *geom, uint8_t variant) wkb_type = WKB_TRIANGLE_TYPE; break; default: - lwerror("Unsupported geometry type: %s [%d]", - lwtype_name(geom->type), geom->type); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(geom->type)); } if ( variant & WKB_EXTENDED ) @@ -723,7 +722,7 @@ static size_t lwgeom_to_wkb_size(const LWGEOM *geom, uint8_t variant) /* Unknown type! */ default: - lwerror("Unsupported geometry type: %s [%d]", lwtype_name(geom->type), geom->type); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(geom->type)); } return size; @@ -771,7 +770,7 @@ static uint8_t* lwgeom_to_wkb_buf(const LWGEOM *geom, uint8_t *buf, uint8_t vari /* Unknown type! */ default: - lwerror("Unsupported geometry type: %s [%d]", lwtype_name(geom->type), geom->type); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(geom->type)); } /* Return value to keep compiler happy. */ return 0; diff --git a/liblwgeom/lwstroke.c b/liblwgeom/lwstroke.c index 8362916f1..2e8099c55 100644 --- a/liblwgeom/lwstroke.c +++ b/liblwgeom/lwstroke.c @@ -577,8 +577,7 @@ lwcompound_linearize(const LWCOMPOUND *icompound, double tol, } else { - lwerror("Unsupported geometry type %d found.", - geom->type, lwtype_name(geom->type)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(geom->type)); return NULL; } } diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index 3e2a15a34..ac3ff10aa 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -390,7 +390,7 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1,const LWGEOM *lwg2, DISTPTS * case CURVEPOLYTYPE: return lw_dist2d_point_curvepoly((LWPOINT *)lwg1, (LWCURVEPOLY *)lwg2, dl); default: - lwerror("Unsupported geometry type: %s", lwtype_name(t2)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(t2)); return LW_FALSE; } } @@ -411,7 +411,7 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1,const LWGEOM *lwg2, DISTPTS * case CURVEPOLYTYPE: return lw_dist2d_line_curvepoly((LWLINE *)lwg1, (LWCURVEPOLY *)lwg2, dl); default: - lwerror("Unsupported geometry type: %s", lwtype_name(t2)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(t2)); return LW_FALSE; } } @@ -433,7 +433,7 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1,const LWGEOM *lwg2, DISTPTS * case CURVEPOLYTYPE: return lw_dist2d_circstring_curvepoly((LWCIRCSTRING *)lwg1, (LWCURVEPOLY *)lwg2, dl); default: - lwerror("Unsupported geometry type: %s", lwtype_name(t2)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(t2)); return LW_FALSE; } } @@ -455,7 +455,7 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1,const LWGEOM *lwg2, DISTPTS * dl->twisted = 1; return lw_dist2d_poly_curvepoly((LWPOLY *)lwg1, (LWCURVEPOLY *)lwg2, dl); default: - lwerror("Unsupported geometry type: %s", lwtype_name(t2)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(t2)); return LW_FALSE; } } @@ -476,13 +476,13 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1,const LWGEOM *lwg2, DISTPTS * dl->twisted = 1; return lw_dist2d_curvepoly_curvepoly((LWCURVEPOLY *)lwg1, (LWCURVEPOLY *)lwg2, dl); default: - lwerror("Unsupported geometry type: %s", lwtype_name(t2)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(t2)); return LW_FALSE; } } default: { - lwerror("Unsupported geometry type: %s", lwtype_name(t1)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(t1)); return LW_FALSE; } } diff --git a/liblwgeom/measures3d.c b/liblwgeom/measures3d.c index b3f1b0b8d..4cb98d27d 100644 --- a/liblwgeom/measures3d.c +++ b/liblwgeom/measures3d.c @@ -589,7 +589,7 @@ lw_dist3d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS3 } else { - lwerror("Unsupported geometry type: %s", lwtype_name(t2)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(t2)); return LW_FALSE; } } @@ -617,7 +617,7 @@ lw_dist3d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS3 } else { - lwerror("Unsupported geometry type: %s", lwtype_name(t2)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(t2)); return LW_FALSE; } } @@ -645,7 +645,7 @@ lw_dist3d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS3 } else { - lwerror("Unsupported geometry type: %s", lwtype_name(t2)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(t2)); return LW_FALSE; } } @@ -673,14 +673,14 @@ lw_dist3d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS3 } else { - lwerror("Unsupported geometry type: %s", lwtype_name(t2)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(t2)); return LW_FALSE; } } else { - lwerror("Unsupported geometry type: %s", lwtype_name(t1)); + lwerror("%s: Unsupported geometry type: %s", __func__, lwtype_name(t1)); return LW_FALSE; } } diff --git a/postgis/geobuf.c b/postgis/geobuf.c index 6170eff40..8264060ce 100644 --- a/postgis/geobuf.c +++ b/postgis/geobuf.c @@ -253,6 +253,23 @@ static Data__Geometry *encode_line(struct geobuf_agg_context *ctx, return geometry; } +static Data__Geometry * +encode_triangle(struct geobuf_agg_context *ctx, LWTRIANGLE *lwtri) +{ + Data__Geometry *geometry = galloc(DATA__GEOMETRY__TYPE__POLYGON); + POINTARRAY *pa = lwtri->points; + uint32_t len; + + if (pa->npoints == 0) + return geometry; + + len = pa->npoints - 1; + geometry->n_coords = len * ctx->dimensions; + geometry->coords = encode_coords(ctx, pa, NULL, len, 0); + + return geometry; +} + static Data__Geometry *encode_mline(struct geobuf_agg_context *ctx, LWMLINE *lwmline) { @@ -415,6 +432,8 @@ static Data__Geometry *encode_geometry(struct geobuf_agg_context *ctx, return encode_point(ctx, (LWPOINT*)lwgeom); case LINETYPE: return encode_line(ctx, (LWLINE*)lwgeom); + case TRIANGLETYPE: + return encode_triangle(ctx, (LWTRIANGLE *)lwgeom); case POLYGONTYPE: return encode_poly(ctx, (LWPOLY*)lwgeom); case MULTIPOINTTYPE: @@ -424,6 +443,7 @@ static Data__Geometry *encode_geometry(struct geobuf_agg_context *ctx, case MULTIPOLYGONTYPE: return encode_mpoly(ctx, (LWMPOLY*)lwgeom); case COLLECTIONTYPE: + case TINTYPE: return encode_collection(ctx, (LWCOLLECTION*)lwgeom); default: elog(ERROR, "encode_geometry: '%s' geometry type not supported", @@ -465,6 +485,7 @@ static void analyze_geometry(struct geobuf_agg_context *ctx, LWGEOM *lwgeom) { case POINTTYPE: case LINETYPE: + case TRIANGLETYPE: lwline = (LWLINE*) lwgeom; analyze_pa(ctx, lwline->points); break; @@ -477,6 +498,7 @@ static void analyze_geometry(struct geobuf_agg_context *ctx, LWGEOM *lwgeom) case MULTILINETYPE: case MULTIPOLYGONTYPE: case COLLECTIONTYPE: + case TINTYPE: lwcollection = (LWCOLLECTION*) lwgeom; for (i = 0; i < lwcollection->ngeoms; i++) analyze_geometry(ctx, lwcollection->geoms[i]); diff --git a/postgis/lwgeom_out_geobuf.c b/postgis/lwgeom_out_geobuf.c index 1221fab5a..5db6c8e5a 100644 --- a/postgis/lwgeom_out_geobuf.c +++ b/postgis/lwgeom_out_geobuf.c @@ -46,14 +46,14 @@ PG_FUNCTION_INFO_V1(pgis_asgeobuf_transfn); Datum pgis_asgeobuf_transfn(PG_FUNCTION_ARGS) { #if ! (defined HAVE_LIBPROTOBUF && defined HAVE_GEOBUF) - elog(ERROR, "Missing libprotobuf-c >= version 1.1"); + elog(ERROR, "ST_AsGeobuf: Missing libprotobuf-c >= version 1.1"); PG_RETURN_NULL(); #else MemoryContext aggcontext; struct geobuf_agg_context *ctx; if (!AggCheckCallContext(fcinfo, &aggcontext)) - elog(ERROR, "pgis_asmvt_transfn: called in non-aggregate context"); + elog(ERROR, "pgis_asgeobuf_transfn: called in non-aggregate context"); MemoryContextSwitchTo(aggcontext); if (PG_ARGISNULL(0)) { @@ -83,7 +83,7 @@ PG_FUNCTION_INFO_V1(pgis_asgeobuf_finalfn); Datum pgis_asgeobuf_finalfn(PG_FUNCTION_ARGS) { #if ! (defined HAVE_LIBPROTOBUF && defined HAVE_GEOBUF) - elog(ERROR, "Missing libprotobuf-c >= version 1.1"); + elog(ERROR, "ST_AsGeoBuf: Missing libprotobuf-c >= version 1.1"); PG_RETURN_NULL(); #else uint8_t *buf; diff --git a/postgis/lwgeom_transform.c b/postgis/lwgeom_transform.c index 02b91b1ee..71ed6c27c 100644 --- a/postgis/lwgeom_transform.c +++ b/postgis/lwgeom_transform.c @@ -56,7 +56,7 @@ Datum transform(PG_FUNCTION_ARGS) srid_to = PG_GETARG_INT32(1); if (srid_to == SRID_UNKNOWN) { - elog(ERROR, "%d is an invalid target SRID", SRID_UNKNOWN); + elog(ERROR, "ST_Transform: %d is an invalid target SRID", SRID_UNKNOWN); PG_RETURN_NULL(); } @@ -66,7 +66,7 @@ Datum transform(PG_FUNCTION_ARGS) if ( srid_from == SRID_UNKNOWN ) { PG_FREE_IF_COPY(geom, 0); - elog(ERROR, "Input geometry has unknown (%d) SRID", SRID_UNKNOWN); + elog(ERROR, "ST_Transform: Input geometry has unknown (%d) SRID", SRID_UNKNOWN); PG_RETURN_NULL(); } @@ -77,7 +77,7 @@ Datum transform(PG_FUNCTION_ARGS) if ( GetPJUsingFCInfo(fcinfo, srid_from, srid_to, &pj) == LW_FAILURE ) { PG_FREE_IF_COPY(geom, 0); - elog(ERROR, "Failure reading projections from spatial_ref_sys."); + elog(ERROR, "ST_Transform: Failure reading projections from spatial_ref_sys."); PG_RETURN_NULL(); } @@ -187,7 +187,7 @@ Datum LWGEOM_asKML(PG_FUNCTION_ARGS) if ( srid_from == SRID_UNKNOWN ) { PG_FREE_IF_COPY(geom, 0); - elog(ERROR, "Input geometry has unknown (%d) SRID", SRID_UNKNOWN); + elog(ERROR, "ST_AsKML: Input geometry has unknown (%d) SRID", SRID_UNKNOWN); PG_RETURN_NULL(); } @@ -217,7 +217,7 @@ Datum LWGEOM_asKML(PG_FUNCTION_ARGS) if (GetPJUsingFCInfo(fcinfo, srid_from, srid_to, &pj) == LW_FAILURE) { PG_FREE_IF_COPY(geom, 0); - elog(ERROR, "Failure reading projections from spatial_ref_sys."); + elog(ERROR, "ST_AsKML: Failure reading projections from spatial_ref_sys."); PG_RETURN_NULL(); } lwgeom_transform(lwgeom, pj); diff --git a/postgis/mvt.c b/postgis/mvt.c index 499799abe..495e64359 100644 --- a/postgis/mvt.c +++ b/postgis/mvt.c @@ -788,11 +788,14 @@ lwgeom_get_basic_type(LWGEOM *geom) case LINETYPE: case POLYGONTYPE: return geom->type; + case TRIANGLETYPE: + return POLYGONTYPE; case MULTIPOINTTYPE: case MULTILINETYPE: case MULTIPOLYGONTYPE: return geom->type - 3; /* Based on LWTYPE positions */ case COLLECTIONTYPE: + case TINTYPE: { uint32_t i; uint8 type = 0; diff --git a/regress/core/geometric_median_expected b/regress/core/geometric_median_expected index ba2e48ff5..c1d2ac97a 100644 --- a/regress/core/geometric_median_expected +++ b/regress/core/geometric_median_expected @@ -1,5 +1,5 @@ t1|t -ERROR: Unsupported geometry type in lwgeom_median +ERROR: lwgeom_median: Unsupported geometry type: LineString t3|t t4|t t5|t diff --git a/regress/core/out_geometry_expected b/regress/core/out_geometry_expected index 6cb37dc51..2ca309568 100644 --- a/regress/core/out_geometry_expected +++ b/regress/core/out_geometry_expected @@ -32,7 +32,7 @@ gml_out_curve_03|5 5 3 5 3 3 0 30 0 2 1 2 2 gml_out_curve_05|-2 0 -1 -1 0 0 1 -1 2 0 0 2 -2 0-1 0 0 0.5 1 0 0 1 -1 07 8 10 10 6 14 4 11 7 8 ERROR: Cannot find SRID (10) in spatial_ref_sys -ERROR: Input geometry has unknown (0) SRID +ERROR: ST_AsKML: Input geometry has unknown (0) SRID kml_empty_geom| kml_precision_01|1,1 kml_precision_02|1.1111111,1.1111111 diff --git a/regress/core/regress_proj_expected b/regress/core/regress_proj_expected index 41cb16bef..b8b51601b 100644 --- a/regress/core/regress_proj_expected +++ b/regress/core/regress_proj_expected @@ -5,7 +5,7 @@ 4|SRID=100001;LINESTRING(574600 5316780,573140 5427940) 5|SRID=100001;LINESTRING(574600 5316780 0 0,573140 5427940 0 0) 6|16.00000000|48.00000000 -ERROR: Input geometry has unknown (0) SRID +ERROR: ST_Transform: Input geometry has unknown (0) SRID 8|SRID=100002;POINT(0 0) 9|POINT(574600 5316780) 10|POINT(574600 5316780) diff --git a/regress/core/tickets.sql b/regress/core/tickets.sql index 9567e6e39..3c0e7fca4 100644 --- a/regress/core/tickets.sql +++ b/regress/core/tickets.sql @@ -1267,3 +1267,39 @@ SELECT '#4445', p1.geom >= p0.geom, p1.geom > p0.geom FROM p0, p1; + + + +WITH geom AS ( + SELECT 'TRIANGLE((0 0, 1 1, 0 1, 0 0))'::geometry geom + union all + SELECT 'TIN(((0 0, 1 1, 0 1, 0 0)))'::geometry geom + union all + SELECT 'TRIANGLE EMPTY'::geometry geom +) +select '#4399', 'ST_AsBinary', ST_AsBinary(geom)::text from geom +union all +select '#4399', 'ST_AsEWKB', ST_AsEWKB(geom)::text from geom +union all +select '#4399', 'ST_AsEWKT', ST_AsEWKT(geom)::text from geom +union all +select '#4399', 'ST_AsGML', ST_AsGML(3,geom)::text from geom +union all +select '#4399', 'ST_AsHEXEWKB', ST_AsHEXEWKB(geom)::text from geom +union all +select '#4399', 'ST_AsKML', ST_AsKML(ST_SetSRID(geom, 4326))::text from geom +union all +select '#4399', 'ST_AsText', ST_AsText(geom)::text from geom +union all +select '#4399', 'ST_AsTWKB', ST_AsTWKB(geom)::text from geom +union all +select '#4399', 'ST_AsX3D', ST_AsX3D(geom)::text from geom +union all +select '#4399', 'ST_GeoHash', ST_GeoHash(geom)::text from geom +union all +select '#4399', 'ST_AsGeobuf', ST_AsGeobuf(geom.*)::text from geom +union all +select '#4399', 'ST_AsMVTGeom', ST_AsMVTGeom(geom, ST_MakeBox2D(ST_Point(0, 0), ST_Point(32, 32)))::text from geom +union all +select '#4399', 'ST_AsGeoJSON', ST_AsGeoJSON(geom)::text from geom; + diff --git a/regress/core/tickets_expected b/regress/core/tickets_expected index e3e0c5f4e..82a5f90b7 100644 --- a/regress/core/tickets_expected +++ b/regress/core/tickets_expected @@ -391,3 +391,40 @@ ERROR: BOX2D_construct: args can not be empty points #4176|t #4394 #4445|f|t|t|t|f|t|t|f|f|f|f|f|f|t|t +#4399|ST_AsBinary|\x0111000000010000000400000000000000000000000000000000000000000000000000f03f000000000000f03f0000000000000000000000000000f03f00000000000000000000000000000000 +#4399|ST_AsBinary|\x0110000000010000000111000000010000000400000000000000000000000000000000000000000000000000f03f000000000000f03f0000000000000000000000000000f03f00000000000000000000000000000000 +#4399|ST_AsBinary|\x011100000000000000 +#4399|ST_AsEWKB|\x0111000000010000000400000000000000000000000000000000000000000000000000f03f000000000000f03f0000000000000000000000000000f03f00000000000000000000000000000000 +#4399|ST_AsEWKB|\x0110000000010000000111000000010000000400000000000000000000000000000000000000000000000000f03f000000000000f03f0000000000000000000000000000f03f00000000000000000000000000000000 +#4399|ST_AsEWKB|\x011100000000000000 +#4399|ST_AsEWKT|TRIANGLE((0 0,1 1,0 1,0 0)) +#4399|ST_AsEWKT|TIN(((0 0,1 1,0 1,0 0))) +#4399|ST_AsEWKT|TRIANGLE EMPTY +#4399|ST_AsGML|0 0 1 1 0 1 0 0 +#4399|ST_AsGML|0 0 1 1 0 1 0 0 +#4399|ST_AsGML| +#4399|ST_AsHEXEWKB|0111000000010000000400000000000000000000000000000000000000000000000000F03F000000000000F03F0000000000000000000000000000F03F00000000000000000000000000000000 +#4399|ST_AsHEXEWKB|0110000000010000000111000000010000000400000000000000000000000000000000000000000000000000F03F000000000000F03F0000000000000000000000000000F03F00000000000000000000000000000000 +#4399|ST_AsHEXEWKB|011100000000000000 +#4399|ST_AsKML|0,0 1,1 0,1 0,0 +#4399|ST_AsKML|0,0 1,1 0,1 0,0 +#4399|ST_AsKML| +#4399|ST_AsText|TRIANGLE((0 0,1 1,0 1,0 0)) +#4399|ST_AsText|TIN(((0 0,1 1,0 1,0 0))) +#4399|ST_AsText|TRIANGLE EMPTY +#4399|ST_AsTWKB|\x030001040000020201000001 +#4399|ST_AsTWKB|\x070001030001040000020201000001 +#4399|ST_AsTWKB|\x0310 +#4399|ST_AsX3D|0 0 1 1 0 1 +#4399|ST_AsX3D| +#4399|ST_AsX3D| +#4399|ST_GeoHash| +#4399|ST_GeoHash| +#4399|ST_GeoHash| +#4399|ST_AsGeobuf|\x180022260a0c0a0a08041a060000020201000a100a0e0806220a08041a060000020201000a040a020804 +#4399|ST_AsMVTGeom|011100000001000000040000000000000000000000000000000000B0400000000000000000000000000000AF400000000000006040000000000000AF400000000000000000000000000000B040 +#4399|ST_AsMVTGeom|011100000001000000040000000000000000000000000000000000B0400000000000000000000000000000AF400000000000006040000000000000AF400000000000000000000000000000B040 +#4399|ST_AsMVTGeom| +#4399|ST_AsGeoJSON|{"type":"Polygon","coordinates":[[[0,0],[1,1],[0,1],[0,0]]]} +#4399|ST_AsGeoJSON|{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[0,0],[1,1],[0,1],[0,0]]]}]} +#4399|ST_AsGeoJSON|{"type":"Polygon","coordinates":[[]]}