static void test_patch_pointn_ght_compression() { // 00 endian (big) // 00000000 pcid // 00000000 compression // 00000003 npoints // 0000000800000003000000050006 pt1 (XYZi) // 0000000200000003000000040008 pt2 (XYZi) // 0000000200000003000000040009 pt3 (XYZi) char *hexbuf = "00000000000000000000000003000000080000000300000005000600000002000000030000000400080000000200000003000000040009"; size_t hexsize = strlen(hexbuf); uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize); PCPATCH *pa = pc_patch_from_wkb(simpleschema, wkb, hexsize/2); PCPOINTLIST *li = pc_pointlist_from_patch(pa); #ifdef HAVE_LIBGHT PCPATCH_GHT* pag = pc_patch_ght_from_pointlist(li); PCPOINT *pt = pc_patch_pointn((PCPATCH*) pag, 2); CU_ASSERT(pt != NULL); CU_ASSERT_STRING_EQUAL(pc_point_to_string(pt), "{\"pcid\":0,\"pt\":[0.02,0.03,0.04,8]}"); pc_patch_free( (PCPATCH*) pag ); pc_point_free(pt); #endif // free pcfree(wkb); pc_patch_free(pa); pc_pointlist_free(li); }
static void test_patch_pointn_laz_compression() { // 00 endian (big) // 00000000 pcid // 00000000 compression // 00000003 npoints // 0000000800000003000000050006 pt1 (XYZi) // 0000000200000003000000040008 pt2 (XYZi) // 0000000200000003000000040009 pt3 (XYZi) char *hexbuf = "00000000000000000000000003000000080000000300000005000600000002000000030000000400080000000200000003000000040009"; size_t hexsize = strlen(hexbuf); uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize); char *str; PCPATCH *pa = pc_patch_from_wkb(simpleschema, wkb, hexsize/2); PCPOINTLIST *li = pc_pointlist_from_patch(pa); PCPATCH_LAZPERF* paz = pc_patch_lazperf_from_pointlist(li); PCPOINT *pt = pc_patch_pointn((PCPATCH*) paz, 2); CU_ASSERT(pt != NULL); str = pc_point_to_string(pt); CU_ASSERT_STRING_EQUAL(str, "{\"pcid\":0,\"pt\":[0.02,0.03,0.04,8]}"); pc_patch_free((PCPATCH *)paz); pc_point_free(pt); pcfree(str); pcfree(wkb); pc_patch_free(pa); pc_pointlist_free(li); }
/* * Can we read this example point value? */ static void test_schema_xy() { /* "Intensity", "ReturnNumber", "NumberOfReturns", "ScanDirectionFlag", "EdgeOfFlightLine", "Classification", "ScanAngleRank", "UserData", "PointSourceId", "Time", "Red", "Green", "Blue", "PointID", "BlockID", "X", "Y", "Z" 25, 1, 1, 1, 0, 1, 6, 124, 7327, 246093, 39, 57, 56, 20, 0, -125.0417204, 49.2540081, 128.85 */ static char *hexpt = "01010000000AE9C90307A1100522A5000019000101010001067C9F1C4953C474650A0E412700390038001400000000000000876B6601962F750155320000"; uint8_t *bytes = bytes_from_hexbytes(hexpt, strlen(hexpt)); PCPOINT *pt; double val; pt = pc_point_from_wkb(lasschema, bytes, strlen(hexpt)/2); pc_point_get_double_by_name(pt, "x", &val); CU_ASSERT_DOUBLE_EQUAL(val, -125.0417204, 0.00001); pc_point_free(pt); pt = pc_point_from_wkb(lasschema, bytes, strlen(hexpt)/2); pc_point_get_double_by_name(pt, "y", &val); CU_ASSERT_DOUBLE_EQUAL(val, 49.2540081, 0.00001); pc_point_free(pt); pcfree(bytes); }
static void test_patch_pointn_last_first() { // 00 endian (big) // 00000000 pcid // 00000000 compression // 00000003 npoints // 0000000800000003000000050006 pt1 (XYZi) // 0000000200000003000000040008 pt2 (XYZi) // 0000000200000003000000040009 pt3 (XYZi) char *hexbuf = "00000000000000000000000003000000080000000300000005000600000002000000030000000400080000000200000003000000040009"; size_t hexsize = strlen(hexbuf); uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize); char *str; PCPATCH *pa = pc_patch_from_wkb(simpleschema, wkb, hexsize/2); PCPOINT *pt = pc_patch_pointn(pa, -1); str = pc_point_to_string(pt); CU_ASSERT_STRING_EQUAL(str, "{\"pcid\":0,\"pt\":[0.02,0.03,0.04,9]}"); pc_point_free(pt); free(str); pt = pc_patch_pointn(pa, -3); str = pc_point_to_string(pt); CU_ASSERT_STRING_EQUAL(str, "{\"pcid\":0,\"pt\":[0.08,0.03,0.05,6]}"); pc_point_free(pt); free(str); pc_patch_free(pa); pcfree(wkb); }
static void test_sort_patch_is_sorted_no_compression() { // 00 endian (big) // 00000000 pcid // 00000000 compression // 00000002 npoints // 0000000800000003000000050006 pt1 (XYZi) // 0000000200000003000000040008 pt2 (XYZi) // 0000000200000003000000040009 pt3 (XYZi) // init data PCPATCH *pasort; char *hexbuf = "00000000000000000000000003000000080000000300000005000600000002000000030000000400080000000200000003000000040009"; size_t hexsize = strlen(hexbuf); uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize); PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2); PCPOINTLIST *li = pc_pointlist_from_patch(pa); const char *X[] = {"X"}; CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X, 1, PC_FALSE), PC_FALSE); CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X, 1, PC_TRUE), PC_FALSE); pasort = pc_patch_sort(pa, X, 1); CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort, X, 1, PC_FALSE), PC_FALSE); CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort, X, 1, PC_TRUE), PC_TRUE); // free pcfree(wkb); pc_patch_free(pa); pc_patch_free(pasort); pc_pointlist_free(li); }
static void test_point_hex_inout() { // byte: endianness (1 = NDR, 0 = XDR) // uint32: pcid (key to POINTCLOUD_SCHEMAS) // uchar[]: pointdata (interpret relative to pcid) double d; char *hexbuf = "00000000010000000100000002000000030004"; size_t hexsize = strlen(hexbuf); uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize); PCPOINT *pt = pc_point_from_wkb(schema, wkb, hexsize/2); pc_point_get_double_by_name(pt, "X", &d); CU_ASSERT_DOUBLE_EQUAL(d, 0.01, 0.000001); pc_point_get_double_by_name(pt, "Y", &d); CU_ASSERT_DOUBLE_EQUAL(d, 0.02, 0.000001); pc_point_get_double_by_name(pt, "Z", &d); CU_ASSERT_DOUBLE_EQUAL(d, 0.03, 0.000001); pc_point_get_double_by_name(pt, "Intensity", &d); CU_ASSERT_DOUBLE_EQUAL(d, 4, 0.0001); pc_point_free(pt); pcfree(wkb); hexbuf = "01010000000100000002000000030000000500"; hexsize = strlen(hexbuf); wkb = bytes_from_hexbytes(hexbuf, hexsize); pt = pc_point_from_wkb(schema, wkb, hexsize/2); pc_point_get_double_by_name(pt, "X", &d); CU_ASSERT_DOUBLE_EQUAL(d, 0.01, 0.000001); pc_point_get_double_by_name(pt, "Y", &d); CU_ASSERT_DOUBLE_EQUAL(d, 0.02, 0.000001); pc_point_get_double_by_name(pt, "Z", &d); CU_ASSERT_DOUBLE_EQUAL(d, 0.03, 0.000001); pc_point_get_double_by_name(pt, "Intensity", &d); CU_ASSERT_DOUBLE_EQUAL(d, 5, 0.0001); pc_point_free(pt); pcfree(wkb); }
PCPATCH * pc_patch_from_hexwkb(const char *hexwkb, size_t hexlen, FunctionCallInfoData *fcinfo) { PCPATCH *patch; PCSCHEMA *schema; uint32 pcid; uint8 *wkb = bytes_from_hexbytes(hexwkb, hexlen); size_t wkblen = hexlen/2; pcid = wkb_get_pcid(wkb); schema = pc_schema_from_pcid(pcid, fcinfo); patch = pc_patch_from_wkb(schema, wkb, wkblen); pfree(wkb); return patch; }
static void test_sort_simple() { // 00 endian (big) // 00000000 pcid // 00000000 compression // 00000002 npoints // 0000000800000003000000050006 pt1 (XYZi) // 0000000200000001000000040008 pt2 (XYZi) // init data PCPOINTLIST *lisort; PCPATCH *pasort; double d1; double d2; char *hexbuf = "0000000000000000000000000200000008000000030000000500060000000200000001000000040008"; size_t hexsize = strlen(hexbuf); uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize); PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2); PCPOINTLIST *li = pc_pointlist_from_patch(pa); const char *X[] = {"X"}; // check that initial data are not sorted pc_point_get_double_by_name(pc_pointlist_get_point(li, 0), "X", &d1); pc_point_get_double_by_name(pc_pointlist_get_point(li, 1), "X", &d2); CU_ASSERT_DOUBLE_EQUAL(d1, 0.08, precision); CU_ASSERT_DOUBLE_EQUAL(d2, 0.02, precision); // sort on X attribute and check if data are well sorted pasort = pc_patch_sort(pa, X, 1); lisort = pc_pointlist_from_patch(pasort); pc_point_get_double_by_name(pc_pointlist_get_point(lisort, 0), "X", &d1); pc_point_get_double_by_name(pc_pointlist_get_point(lisort, 1), "X", &d2); CU_ASSERT_DOUBLE_EQUAL(d1, 0.02, precision); CU_ASSERT_DOUBLE_EQUAL(d2, 0.08, precision); // free pc_pointlist_free(li); pc_pointlist_free(lisort); pc_patch_free(pa); pc_patch_free(pasort); pcfree(wkb); }
static void test_sort_consistency() { // 00 endian (big) // 00000000 pcid // 00000000 compression // 00000002 npoints // 0000000800000003000000050006 pt1 (XYZi) // 0000000200000001000000040008 pt2 (XYZi) // init data PCPATCH *pasort; char *pastr, *pasortstr; uint8_t *wkbsort; char *hexbuf = "0000000000000000000000000200000008000000030000000500060000000200000001000000040008"; size_t hexsize = strlen(hexbuf); uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize); PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2); PCPOINTLIST *li = pc_pointlist_from_patch(pa); const char *X[] = {"X"}; // sort on X attribute pasort = pc_patch_sort(pa, X, 1); //chek consistency wkbsort = pc_patch_to_wkb(pasort, &hexsize); CU_ASSERT_EQUAL(wkb_get_pcid(wkb), wkb_get_pcid(wkbsort)); CU_ASSERT_EQUAL(wkb_get_npoints(wkb), wkb_get_npoints(wkbsort)); CU_ASSERT_EQUAL(wkb_get_compression(wkb), wkb_get_compression(wkbsort)); pastr = pc_patch_to_string(pa); CU_ASSERT_STRING_EQUAL(pastr, "{\"pcid\":0,\"pts\":[[0.08,0.03,0.05,6],[0.02,0.01,0.04,8]]}"); pasortstr = pc_patch_to_string(pasort); CU_ASSERT_STRING_EQUAL(pasortstr, "{\"pcid\":0,\"pts\":[[0.02,0.01,0.04,8],[0.08,0.03,0.05,6]]}"); // free pcfree(wkb); pcfree(wkbsort); pcfree(pastr); pcfree(pasortstr); pc_patch_free(pasort); pc_patch_free(pa); pc_pointlist_free(li); }
LWGEOM* lwgeom_from_hexwkb(const char *hexwkb, const char check) { int hexwkb_len; uint8_t *wkb; LWGEOM *lwgeom; if ( ! hexwkb ) { lwerror("lwgeom_from_hexwkb: null input"); return NULL; } hexwkb_len = strlen(hexwkb); wkb = bytes_from_hexbytes(hexwkb, hexwkb_len); lwgeom = lwgeom_from_wkb(wkb, hexwkb_len/2, check); lwfree(wkb); return lwgeom; }
static void test_sort_patch_ndims() { // 00 endian (big) // 00000000 pcid // 00000000 compression // 00000002 npoints // 0000000800000001000000050006 pt1 (XYZi) // 0000000200000003000000040008 pt2 (XYZi) // 0000000200000002000000040008 pt2 (XYZi) // init data PCPATCH *pasort1, *pasort2; char *hexbuf = "00000000000000000000000003000000080000000400000005000600000002000000030000000400080000000200000002000000040009"; size_t hexsize = strlen(hexbuf); uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize); PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2); const char *X[] = {"X"}; const char *Y[] = {"Y"}; const char *X_Y[] = {"X", "Y"}; // test that initial data is not sorted CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X, 1, PC_FALSE), PC_FALSE); CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, Y, 1, PC_FALSE), PC_FALSE); CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X_Y, 2, PC_FALSE), PC_FALSE); // sort on X attribute and test pasort1 = pc_patch_sort(pa, X, 1); CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort1, X, 1, PC_TRUE), PC_TRUE); CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort1, Y, 1, PC_TRUE), PC_FALSE); CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort1, X_Y, 2, PC_TRUE), PC_FALSE); // sort on X and Y and tst pasort2 = pc_patch_sort(pa, X_Y, 2); CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort2, X, 1, PC_TRUE), PC_TRUE); CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort2, Y, 1, PC_TRUE), PC_TRUE); CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort2, X_Y, 2, PC_TRUE), PC_TRUE); // free pcfree(wkb); pc_patch_free(pasort1); pc_patch_free(pasort2); pc_patch_free(pa); }
PCPATCH * pc_patch_from_hexwkb(const char *hexwkb, size_t hexlen, FunctionCallInfoData *fcinfo) { PCPATCH *patch; PCSCHEMA *schema; uint32 pcid; uint8 *wkb = bytes_from_hexbytes(hexwkb, hexlen); size_t wkblen = hexlen/2; pcid = wkb_get_pcid(wkb); if ( ! pcid ) elog(ERROR, "%s: pcid is zero", __func__); schema = pc_schema_from_pcid(pcid, fcinfo); if ( ! schema ) elog(ERROR, "%s: unable to look up schema entry", __func__); patch = pc_patch_from_wkb(schema, wkb, wkblen); pfree(wkb); return patch; }
static void test_patch_hex_in() { // 00 endian (big) // 00000000 pcid // 00000000 compression // 00000002 npoints // 0000000200000003000000050006 pt1 (XYZi) // 0000000200000003000000050008 pt2 (XYZi) char *hexbuf = "0000000000000000000000000200000002000000030000000500060000000200000003000000050008"; double d; char *str; size_t hexsize = strlen(hexbuf); uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize); PCPATCH *pa = pc_patch_from_wkb(simpleschema, wkb, hexsize/2); PCPOINTLIST *pl = pc_pointlist_from_patch(pa); pc_point_get_double_by_name(pc_pointlist_get_point(pl, 0), "X", &d); CU_ASSERT_DOUBLE_EQUAL(d, 0.02, 0.000001); pc_point_get_double_by_name(pc_pointlist_get_point(pl, 1), "Intensity", &d); CU_ASSERT_DOUBLE_EQUAL(d, 8, 0.000001); pc_point_get_double_by_name(&(pa->stats->min), "Intensity", &d); CU_ASSERT_DOUBLE_EQUAL(d, 6, 0.000001); pc_point_get_double_by_name(&(pa->stats->max), "Intensity", &d); CU_ASSERT_DOUBLE_EQUAL(d, 8, 0.000001); pc_point_get_double_by_name(&(pa->stats->avg), "Intensity", &d); CU_ASSERT_DOUBLE_EQUAL(d, 7, 0.000001); str = pc_patch_to_string(pa); CU_ASSERT_STRING_EQUAL(str, "{\"pcid\":0,\"pts\":[[0.02,0.03,0.05,6],[0.02,0.03,0.05,8]]}"); // printf("\n%s\n",str); pcfree(str); pc_pointlist_free(pl); pc_patch_free(pa); pcfree(wkb); }
static void test_sort_stable() { // 00 endian (big) // 00000000 pcid // 00000000 compression // 00000002 npoints // 0000000800000003000000050006 pt1 (XYZi) // 0000000200000003000000040008 pt2 (XYZi) // 0000000200000003000000040009 pt3 (XYZi) // init data PCPATCH *pasort; char *hexbuf = "00000000000000000000000003000000080000000300000005000600000002000000030000000400080000000200000003000000040009"; size_t hexsize = strlen(hexbuf); uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize); PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2); PCPOINTLIST *li = pc_pointlist_from_patch(pa); const char *dims[] = {"Y"}; // sort on Y attribute pasort = pc_patch_sort(pa, dims, 1); // check that sort is stable char *pastr = pc_patch_to_string(pa); char *pasortstr = pc_patch_to_string(pasort); CU_ASSERT_STRING_EQUAL(pastr, pasortstr); // free free(pastr); free(pasortstr); pcfree(wkb); pc_patch_free(pa); pc_patch_free(pasort); pc_pointlist_free(li); }
Datum LWGEOM_in(PG_FUNCTION_ARGS) { char *input = PG_GETARG_CSTRING(0); int32 geom_typmod = -1; char *str = input; LWGEOM_PARSER_RESULT lwg_parser_result; LWGEOM *lwgeom; GSERIALIZED *ret; int srid = 0; if ( (PG_NARGS()>2) && (!PG_ARGISNULL(2)) ) { geom_typmod = PG_GETARG_INT32(2); } lwgeom_parser_result_init(&lwg_parser_result); /* Empty string. */ if ( str[0] == '\0' ) ereport(ERROR,(errmsg("parse error - invalid geometry"))); /* Starts with "SRID=" */ if( strncasecmp(str,"SRID=",5) == 0 ) { /* Roll forward to semi-colon */ char *tmp = str; while ( tmp && *tmp != ';' ) tmp++; /* Check next character to see if we have WKB */ if ( tmp && *(tmp+1) == '0' ) { /* Null terminate the SRID= string */ *tmp = '\0'; /* Set str to the start of the real WKB */ str = tmp + 1; /* Move tmp to the start of the numeric part */ tmp = input + 5; /* Parse out the SRID number */ srid = atoi(tmp); } } /* WKB? Let's find out. */ if ( str[0] == '0' ) { size_t hexsize = strlen(str); unsigned char *wkb = bytes_from_hexbytes(str, hexsize); /* TODO: 20101206: No parser checks! This is inline with current 1.5 behavior, but needs discussion */ lwgeom = lwgeom_from_wkb(wkb, hexsize/2, LW_PARSER_CHECK_NONE); /* If we picked up an SRID at the head of the WKB set it manually */ if ( srid ) lwgeom_set_srid(lwgeom, srid); /* Add a bbox if necessary */ if ( lwgeom_needs_bbox(lwgeom) ) lwgeom_add_bbox(lwgeom); pfree(wkb); ret = geometry_serialize(lwgeom); lwgeom_free(lwgeom); } /* WKT then. */ else { if ( lwgeom_parse_wkt(&lwg_parser_result, str, LW_PARSER_CHECK_ALL) == LW_FAILURE ) { PG_PARSER_ERROR(lwg_parser_result); } lwgeom = lwg_parser_result.geom; if ( lwgeom_needs_bbox(lwgeom) ) lwgeom_add_bbox(lwgeom); ret = geometry_serialize(lwgeom); lwgeom_parser_result_free(&lwg_parser_result); } if ( geom_typmod >= 0 ) { postgis_valid_typmod(ret, geom_typmod); POSTGIS_DEBUG(3, "typmod and geometry were consistent"); } else { POSTGIS_DEBUG(3, "typmod was -1"); } /* Don't free the parser result (and hence lwgeom) until we have done */ /* the typemod check with lwgeom */ PG_RETURN_POINTER(ret); }