/** * Build a new #POINTARRAY, but on top of someone else's ordinate array. * Flag as read-only, so that ptarray_free() does not free the serialized_ptlist */ POINTARRAY* ptarray_construct_reference_data(char hasz, char hasm, uint32_t npoints, uint8_t *ptlist) { POINTARRAY *pa = (POINTARRAY *)lwalloc(sizeof(POINTARRAY)); LWDEBUGF(5, "hasz = %d, hasm = %d, npoints = %d, ptlist = %p", hasz, hasm, npoints, ptlist); pa->flags = gflags(hasz, hasm, 0); FLAGS_SET_READONLY(pa->flags, 1); /* We don't own this memory, so we can't alter or free it. */ pa->npoints = npoints; pa->maxpoints = npoints; pa->serialized_pointlist = ptlist; return pa; }
/* Deep clone LWPOLY object. POINTARRAY are copied, as is ring array */ LWPOLY * lwpoly_clone_deep(const LWPOLY *g) { int i; LWPOLY *ret = lwalloc(sizeof(LWPOLY)); memcpy(ret, g, sizeof(LWPOLY)); if ( g->bbox ) ret->bbox = gbox_copy(g->bbox); ret->rings = lwalloc(sizeof(POINTARRAY *)*g->nrings); for ( i = 0; i < ret->nrings; i++ ) { ret->rings[i] = ptarray_clone_deep(g->rings[i]); } FLAGS_SET_READONLY(ret->flags,0); return ret; }
/** * @brief Clone a POINTARRAY object. Serialized pointlist is not copied. */ POINTARRAY * ptarray_clone(const POINTARRAY *in) { POINTARRAY *out = (POINTARRAY *)lwalloc(sizeof(POINTARRAY)); LWDEBUG(3, "ptarray_clone_deep called."); out->flags = in->flags; out->npoints = in->npoints; out->maxpoints = in->maxpoints; FLAGS_SET_READONLY(out->flags, 1); out->serialized_pointlist = in->serialized_pointlist; return out; }
/** * @brief Deep clone a pointarray (also clones serialized pointlist) */ POINTARRAY * ptarray_clone_deep(const POINTARRAY *in) { POINTARRAY *out = (POINTARRAY *)lwalloc(sizeof(POINTARRAY)); size_t size; LWDEBUG(3, "ptarray_clone_deep called."); out->flags = in->flags; out->npoints = in->npoints; out->maxpoints = in->maxpoints; FLAGS_SET_READONLY(out->flags, 0); size = in->npoints * ptarray_point_size(in); out->serialized_pointlist = (uint8_t *)lwalloc(size); memcpy(out->serialized_pointlist, in->serialized_pointlist, size); return out; }
static void test_ptarray_append_ptarray(void) { LWLINE *line1, *line2; int ret; char *wkt; /* Empty first line */ line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING EMPTY")); line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,0 10,5 5)")); ret = ptarray_append_ptarray(line1->points, line2->points, -1); CU_ASSERT(ret == LW_SUCCESS); wkt = lwgeom_to_text(lwline_as_lwgeom(line1)); CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(0 0,0 10,5 5)"); lwfree(wkt); lwline_free(line2); lwline_free(line1); /* Empty second line */ line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0, 5 5, 6 3)")); line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING EMPTY")); ret = ptarray_append_ptarray(line1->points, line2->points, -1); CU_ASSERT(ret == LW_SUCCESS); wkt = lwgeom_to_text(lwline_as_lwgeom(line1)); CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(0 0,5 5,6 3)"); lwfree(wkt); lwline_free(line2); lwline_free(line1); /* Both lines empty */ line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING EMPTY")); line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING EMPTY")); ret = ptarray_append_ptarray(line1->points, line2->points, -1); CU_ASSERT(ret == LW_SUCCESS); wkt = lwgeom_to_text(lwline_as_lwgeom(line1)); CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING EMPTY"); lwfree(wkt); lwline_free(line2); lwline_free(line1); /* Sane sewing */ line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 4, 0 0,5 7)")); line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(5 7,12 43, 42 15)")); ret = ptarray_append_ptarray(line1->points, line2->points, 0); CU_ASSERT(ret == LW_SUCCESS); wkt = lwgeom_to_text(lwline_as_lwgeom(line1)); CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(10 4,0 0,5 7,12 43,42 15)"); lwfree(wkt); lwline_free(line2); lwline_free(line1); /* Untolerated sewing */ line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 4, 0 0,5 7)")); line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(5.5 7,12 43, 42 15)")); ret = ptarray_append_ptarray(line1->points, line2->points, 0); CU_ASSERT(ret == LW_FAILURE); lwline_free(line2); lwline_free(line1); /* Tolerated sewing */ line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 4, 0 0,5 7)")); line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(5.5 7,12 43, 42 15)")); ret = ptarray_append_ptarray(line1->points, line2->points, .7); CU_ASSERT(ret == LW_SUCCESS); wkt = lwgeom_to_text(lwline_as_lwgeom(line1)); CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(10 4,0 0,5 7,5.5 7,12 43,42 15)"); lwfree(wkt); lwline_free(line2); lwline_free(line1); /* Check user input trust (creates non-simple line */ line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,0 10)")); line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0,0 10)")); ret = ptarray_append_ptarray(line1->points, line2->points, -1); CU_ASSERT(ret == LW_SUCCESS); wkt = lwgeom_to_text(lwline_as_lwgeom(line1)); CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(0 0,0 10,0 0,0 10)"); lwfree(wkt); lwline_free(line2); lwline_free(line1); /* Mixed dimensionality is not allowed */ line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 10 0, 10 0 0)")); line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 0,11 0)")); ret = ptarray_append_ptarray(line1->points, line2->points, -1); CU_ASSERT(ret == LW_FAILURE); lwline_free(line2); lwline_free(line1); /* Appending a read-only pointarray is allowed */ line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 10, 10 0)")); line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 0,11 0)")); FLAGS_SET_READONLY(line2->points->flags, 1); ret = ptarray_append_ptarray(line1->points, line2->points, -1); CU_ASSERT(ret == LW_SUCCESS); wkt = lwgeom_to_text(lwline_as_lwgeom(line1)); CU_ASSERT_STRING_EQUAL(wkt, "LINESTRING(0 10,10 0,11 0)"); lwfree(wkt); FLAGS_SET_READONLY(line2->points->flags, 0); /* for lwline_free */ lwline_free(line2); lwline_free(line1); /* Appending to a read-only pointarray is forbidden */ line1 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 10, 10 0)")); line2 = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(10 0,11 0)")); FLAGS_SET_READONLY(line1->points->flags, 1); ret = ptarray_append_ptarray(line1->points, line2->points, -1); CU_ASSERT(ret == LW_FAILURE); lwline_free(line2); FLAGS_SET_READONLY(line1->points->flags, 0); /* for lwline_free */ lwline_free(line1); }