/* ** Creating an input WKB from a wkb string */ static void cu_wkb(char *wkt) { LWGEOM *g = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_NONE); if ( s ) free(s); s = (char*)lwgeom_to_wkb(g, WKB_HEX | WKB_XDR | WKB_EXTENDED, NULL); lwgeom_free(g); }
/* ** Creating an input from a hexwkb */ static void cu_wkb_from_hexwkb(char *hexwkb) { LWGEOM *g = lwgeom_from_hexwkb(hexwkb, LW_PARSER_CHECK_NONE); if ( s ) free(s); s = (char*)lwgeom_to_wkb(g, WKB_HEX | WKB_XDR | WKB_EXTENDED, 0); lwgeom_free(g); }
Datum geography_as_binary(PG_FUNCTION_ARGS) { LWGEOM *lwgeom = NULL; uint8_t *wkb = NULL; bytea *wkb_result; size_t wkb_size = 0; GSERIALIZED *g = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); /* Get our lwgeom form */ lwgeom = lwgeom_from_gserialized(g); if ( gserialized_ndims(g) > 2 ) { /* Strip out the higher dimensions */ LWGEOM *tmp = lwgeom_force_2d(lwgeom); lwgeom_free(lwgeom); lwgeom = tmp; } /* Create WKB */ wkb = lwgeom_to_wkb(lwgeom, WKB_SFSQL, &wkb_size); /* Copy to varlena pointer */ wkb_result = palloc(wkb_size + VARHDRSZ); SET_VARSIZE(wkb_result, wkb_size + VARHDRSZ); memcpy(VARDATA(wkb_result), wkb, wkb_size); /* Clean up */ pfree(wkb); lwgeom_free(lwgeom); PG_RETURN_BYTEA_P(wkb_result); }
static void cu_wkb_in(char *wkt) { LWGEOM_PARSER_RESULT pr; LWGEOM *g_a, *g_b; uint8_t *wkb_a, *wkb_b; size_t wkb_size_a, wkb_size_b; /* int i; char *hex; */ if ( hex_a ) free(hex_a); if ( hex_b ) free(hex_b); /* Turn WKT into geom */ lwgeom_parse_wkt(&pr, wkt, LW_PARSER_CHECK_NONE); if ( pr.errcode ) { printf("ERROR: %s\n", pr.message); printf("POSITION: %d\n", pr.errlocation); exit(0); } /* Get the geom */ g_a = pr.geom; /* Turn geom into WKB */ wkb_a = lwgeom_to_wkb(g_a, WKB_NDR | WKB_EXTENDED, &wkb_size_a); /* Turn WKB back into geom */ g_b = lwgeom_from_wkb(wkb_a, wkb_size_a, LW_PARSER_CHECK_NONE); /* Turn geom to WKB again */ wkb_b = lwgeom_to_wkb(g_b, WKB_NDR | WKB_EXTENDED, &wkb_size_b); /* Turn geoms into WKB for comparisons */ hex_a = hexbytes_from_bytes(wkb_a, wkb_size_a); hex_b = hexbytes_from_bytes(wkb_b, wkb_size_b); /* Clean up */ lwfree(wkb_a); lwfree(wkb_b); lwgeom_parser_result_free(&pr); lwgeom_free(g_b); }
// trying to make polygon to be valid // accept only string-polygon in wkb format static VALUE make_valid(VALUE self, VALUE geom_wkb) { VALUE result; LWGEOM *valid_lwg; int wkb_size_a; wkb_size_a = RSTRING_LEN(geom_wkb); lwg = lwgeom_from_wkb(RSTRING_PTR(geom_wkb), wkb_size_a, 0); valid_lwg = lwgeom_make_valid(lwg); //make multi valid_lwg = lwgeom_as_multi(valid_lwg); char *wkb_str = (char*)lwgeom_to_wkb(valid_lwg, WKB_HEX, NULL); return rb_str_new2(wkb_str); }
Datum LWGEOM_asBinary(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom; uint8_t *wkb; size_t wkb_size; bytea *result; uint8_t variant = WKB_ISO; /* Get a 2D version of the geometry */ geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); lwgeom = lwgeom_from_gserialized(geom); /* If user specified endianness, respect it */ if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) ) { text *wkb_endian = PG_GETARG_TEXT_P(1); if ( ! strncmp(VARDATA(wkb_endian), "xdr", 3) || ! strncmp(VARDATA(wkb_endian), "XDR", 3) ) { variant = variant | WKB_XDR; } else { variant = variant | WKB_NDR; } } /* Write to WKB and free the geometry */ wkb = lwgeom_to_wkb(lwgeom, variant, &wkb_size); lwgeom_free(lwgeom); /* Write to text and free the WKT */ result = palloc(wkb_size + VARHDRSZ); memcpy(VARDATA(result), wkb, wkb_size); SET_VARSIZE(result, wkb_size + VARHDRSZ); pfree(wkb); /* Return the text */ PG_FREE_IF_COPY(geom, 0); PG_RETURN_BYTEA_P(result); }
Datum geography_send(PG_FUNCTION_ARGS) { LWGEOM *lwgeom = NULL; GSERIALIZED *g = NULL; size_t size_result; uint8_t *wkb; bytea *result; g = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); lwgeom = lwgeom_from_gserialized(g); wkb = lwgeom_to_wkb(lwgeom, WKB_EXTENDED, &size_result); lwgeom_free(lwgeom); result = palloc(size_result + VARHDRSZ); SET_VARSIZE(result, size_result + VARHDRSZ); memcpy(VARDATA(result), wkb, size_result); pfree(wkb); PG_RETURN_POINTER(result); }
Datum WKBFromLWGEOM(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); LWGEOM *lwgeom; uint8_t *wkb; size_t wkb_size; uint8_t variant = 0; bytea *result; text *type; /* If user specified endianness, respect it */ if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) ) { type = PG_GETARG_TEXT_P(1); if ( ! strncmp(VARDATA(type), "xdr", 3) || ! strncmp(VARDATA(type), "XDR", 3) ) { variant = variant | WKB_XDR; } else { variant = variant | WKB_NDR; } } /* Create WKB hex string */ lwgeom = lwgeom_from_gserialized(geom); wkb = lwgeom_to_wkb(lwgeom, variant | WKB_EXTENDED , &wkb_size); lwgeom_free(lwgeom); /* Prepare the PgSQL text return type */ result = palloc(wkb_size + VARHDRSZ); memcpy(VARDATA(result), wkb, wkb_size); SET_VARSIZE(result, wkb_size+VARHDRSZ); /* Clean up and return */ pfree(wkb); PG_FREE_IF_COPY(geom, 0); PG_RETURN_BYTEA_P(result); }
void polyhedralsurface_parse(void) { LWGEOM *geom; GSERIALIZED *g; char *tmp; cu_error_msg_reset(); /* Because i don't trust that much prior tests... ;) */ /* 2 dims */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1,2 3,4 5,0 1)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F00000001000000010300000001000000040000000000000000000000000000000000F03F00000000000000400000000000000840000000000000104000000000000014400000000000000000000000000000F03F", tmp); lwfree(tmp); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE(((0 1,2 3,4 5,0 1)))", tmp); lwfree(tmp); lwgeom_free(geom); /* 3DM */ geom = lwgeom_from_wkt("POLYHEDRALSURFACEM(((0 1 2,3 4 5,6 7 8,0 1 2)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACEM(((0 1 2,3 4 5,6 7 8,0 1 2)))", tmp); lwfree(tmp); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F00004001000000010300004001000000040000000000000000000000000000000000F03F000000000000004000000000000008400000000000001040000000000000144000000000000018400000000000001C4000000000000020400000000000000000000000000000F03F0000000000000040", tmp); lwfree(tmp); lwgeom_free(geom); /* ERROR: a missing Z values */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7,0 1 2)))", LW_PARSER_CHECK_NONE); CU_ASSERT_STRING_EQUAL("can not mix dimensionality in a geometry", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* 1 face with 1 interior ring */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7 8,0 1 2),(9 10 11,12 13 14,15 16 17,9 10 11)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7 8,0 1 2),(9 10 11,12 13 14,15 16 17,9 10 11)))", tmp); lwfree(tmp); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F00008001000000010300008002000000040000000000000000000000000000000000F03F000000000000004000000000000008400000000000001040000000000000144000000000000018400000000000001C4000000000000020400000000000000000000000000000F03F00000000000000400400000000000000000022400000000000002440000000000000264000000000000028400000000000002A400000000000002C400000000000002E4000000000000030400000000000003140000000000000224000000000000024400000000000002640", tmp); lwfree(tmp); lwgeom_free(geom); /* ERROR: non closed rings */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7 8,0 0 2)))", LW_PARSER_CHECK_ALL); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: non closed face in Z dim */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7 8,0 1 3)))", LW_PARSER_CHECK_ALL); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: non closed face in Z dim, with a 4D geom */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2 3,4 5 6 7,8 9 10 11,0 1 3 3)))", LW_PARSER_CHECK_ALL); CU_ASSERT_STRING_EQUAL("geometry contains non-closed rings", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* ERROR: only 3 points in a face */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,0 1 2)))", LW_PARSER_CHECK_ALL); CU_ASSERT_STRING_EQUAL("geometry requires more points", cu_error_msg); cu_error_msg_reset(); lwgeom_free(geom); /* EMPTY face */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE EMPTY", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); tmp = (char *)lwgeom_to_wkb(geom, WKB_HEX | WKB_ISO | WKB_NDR, 0); CU_ASSERT_STRING_EQUAL("010F00000000000000", tmp); lwfree(tmp); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE EMPTY", tmp); lwfree(tmp); lwgeom_free(geom); /* A simple tetrahedron */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); CU_ASSERT_EQUAL(geom->srid, SRID_UNKNOWN); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", tmp); lwfree(tmp); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F000080040000000103000080010000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000010300008001000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000000001030000800100000004000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000000001030000800100000004000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F00000000000000000000000000000000", tmp); lwfree(tmp); lwgeom_free(geom); /* A 4D tetrahedron */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 0 0 0,0 0 1 0,0 1 0 2,0 0 0 0)),((0 0 0 0,0 1 0 0,1 0 0 4,0 0 0 0)),((0 0 0 0,1 0 0 0,0 0 1 6,0 0 0 0)),((1 0 0 0,0 1 0 0,0 0 1 0,1 0 0 0)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); CU_ASSERT_EQUAL(FLAGS_GET_M(geom->flags), 1); CU_ASSERT_EQUAL(geom->srid, SRID_UNKNOWN); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE(((0 0 0 0,0 0 1 0,0 1 0 2,0 0 0 0)),((0 0 0 0,0 1 0 0,1 0 0 4,0 0 0 0)),((0 0 0 0,1 0 0 0,0 0 1 6,0 0 0 0)),((1 0 0 0,0 1 0 0,0 0 1 0,1 0 0 0)))", tmp); lwfree(tmp); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F0000C00400000001030000C00100000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000F03F00000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000001030000C0010000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000F03F000000000000000000000000000000000000000000001040000000000000000000000000000000000000000000000000000000000000000001030000C001000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000001840000000000000000000000000000000000000000000000000000000000000000001030000C00100000004000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000000000000000000000000000000000000000", tmp); lwfree(tmp); lwgeom_free(geom); /* explicit SRID */ geom = lwgeom_from_wkt("SRID=4326;POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); CU_ASSERT_EQUAL(geom->srid, 4326); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("SRID=4326;POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", tmp); lwfree(tmp); tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F0000A0E6100000040000000103000080010000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000010300008001000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000000001030000800100000004000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000000001030000800100000004000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F00000000000000000000000000000000", tmp); lwfree(tmp); lwgeom_free(geom); /* geography support */ geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7 8,0 1 2)))", LW_PARSER_CHECK_NONE); g = gserialized_from_lwgeom(geom, 1, 0); CU_ASSERT_EQUAL(gserialized_get_type(g), POLYHEDRALSURFACETYPE); lwgeom_free(geom); lwfree(g); }