[postgis-devel] Re: [postgis-users] how to identify the_geom
that cause : RelateOperation called withLWGEOMCOLLECTION type
Kevin Neufeld
kneufeld at refractions.net
Tue Dec 9 11:50:52 PST 2008
Thanx Mark,
Here's an updated patch. I didn't put the truncation logic in a separate function yet since I'm not sure about freeing
the memory of a returned char* (looking through the code, sometimes pfree is called, and other times it's not).
Cheers,
Kevin
Mark Cave-Ayland wrote:
> Kevin Neufeld wrote:
>
>> Mark,
>>
>> Is it fairly trivial to change the elog in lwgeom_geos.c to your fancy
>> errhint so that when the error is thrown the user has an idea where
>> the problem occurs?
>
> Yeah sure. In fact, elog() has been deprecated for a very long time and
> so in theory we should be using ereport() everywhere.
>
>> The attached patch seems to work, but I got lost when trying to limit
>> the output of the LWGEOMCOLLECTION to the first say 128 characters of
>> the WKT representation.
>
> Yup, code looks good. The only comment is that you want
> PARSER_CHECK_NONE instead of PARSER_CHECK_ALL, otherwise the conversion
> will fail on a non-OGC compliant geometry. So in other words, you only
> really want PARSER_CHECK_ALL on the input/output functions.
>
> In terms of truncating the output, you need to do this manually - see
> http://svn.refractions.net/postgis/trunk/lwgeom/lwgeom_pg.c:pg_parser_errhint
> for the code I used, although if it is needed in multiple places it may
> be a good idea to make this a separate function available in liblwgeom.
>
>
> HTH,
>
> Mark.
>
-------------- next part --------------
Index: lwgeom_geos.c
===================================================================
--- lwgeom_geos.c (revision 3371)
+++ lwgeom_geos.c (working copy)
@@ -1020,14 +1020,55 @@
/*---------------------------------------------*/
-
+/*
+ * Throws an ereport ERROR if either geometry is a COLLECTIONTYPE. Additionally
+ * displays a HINT of the first 80 characters of the WKT representation of the
+ * problematic geometry so a user knows which parameter and which geometry
+ * is causing the problem.
+ */
void errorIfGeometryCollection(PG_LWGEOM *g1, PG_LWGEOM *g2)
{
int t1 = lwgeom_getType(g1->type);
int t2 = lwgeom_getType(g2->type);
+
+ // Define the hint string include the first 80 characters of the problematic geometry.
+ char hintbuffer[80];
+
+ LWGEOM_UNPARSER_RESULT lwg_unparser_result;
+ int result;
+
+ hintbuffer[0] = '\0';
- if ( (t1 == COLLECTIONTYPE) || (t2 == COLLECTIONTYPE) )
- elog(ERROR,"Relate Operation called with a LWGEOMCOLLECTION type. This is unsupported");
+ if ( t1 == COLLECTIONTYPE) {
+ result = serialized_lwgeom_to_ewkt(&lwg_unparser_result, SERIALIZED_FORM(g1), PARSER_CHECK_NONE);
+ if (strlen(lwg_unparser_result.wkoutput) < 80) {
+ strcpy(hintbuffer, lwg_unparser_result.wkoutput);
+ }
+ else {
+ strncat(hintbuffer, lwg_unparser_result.wkoutput, 76);
+ strcat(hintbuffer, "...");
+ }
+
+ ereport(ERROR,
+ (errmsg("Relate Operation called with a LWGEOMCOLLECTION type. This is unsupported."),
+ errhint("Change argument 1: '%s'", hintbuffer))
+ );
+ }
+ else if (t2 == COLLECTIONTYPE) {
+ result = serialized_lwgeom_to_ewkt(&lwg_unparser_result, SERIALIZED_FORM(g2), PARSER_CHECK_NONE);
+ if (strlen(lwg_unparser_result.wkoutput) < 80) {
+ strcpy(hintbuffer, lwg_unparser_result.wkoutput);
+ }
+ else {
+ strncat(hintbuffer, lwg_unparser_result.wkoutput, 76);
+ strcat(hintbuffer, "...");
+ }
+
+ ereport(ERROR,
+ (errmsg("Relate Operation called with a LWGEOMCOLLECTION type. This is unsupported."),
+ errhint("Change argument 2: '%s'", hintbuffer))
+ );
+ }
}
PG_FUNCTION_INFO_V1(isvalid);