예제 #1
0
static void
test_dimension_get()
{
	PCDIMENSION *d;

	d = pc_schema_get_dimension(schema, 0);
	CU_ASSERT_EQUAL(d->position, 0);
	CU_ASSERT_STRING_EQUAL(d->name, "X");

	d = pc_schema_get_dimension(schema, 1);
	CU_ASSERT_EQUAL(d->position, 1);
	CU_ASSERT_STRING_EQUAL(d->name, "Y");

	d = pc_schema_get_dimension_by_name(schema, "nothinghere");
	CU_ASSERT_EQUAL(d, NULL);

	d = pc_schema_get_dimension_by_name(schema, "Z");
	CU_ASSERT_EQUAL(d->position, 2);
	CU_ASSERT_STRING_EQUAL(d->name, "Z");

	d = pc_schema_get_dimension_by_name(schema, "z");
	CU_ASSERT_EQUAL(d->position, 2);
	CU_ASSERT_STRING_EQUAL(d->name, "Z");

	d = pc_schema_get_dimension_by_name(schema, "y");
	// printf("name %s\n", d->name);
	// printf("position %d\n", d->position);
	CU_ASSERT_EQUAL(d->position, 1);
	CU_ASSERT_STRING_EQUAL(d->name, "Y");
}
예제 #2
0
PCPOINTLIST *
pc_pointlist_from_dimensional(const PCPATCH_DIMENSIONAL *pdl)
{
	PCPOINTLIST *pl;
	PCPATCH_DIMENSIONAL *pdl_uncompressed;
	const PCSCHEMA *schema = pdl->schema;
	int i, j, ndims, npoints;
	assert(pdl);

	pdl_uncompressed = pc_patch_dimensional_decompress(pdl);

	ndims = schema->ndims;
	npoints = pdl->npoints;
	pl = pc_pointlist_make(npoints);

	for ( i = 0; i < npoints; i++ )
	{
		PCPOINT *pt = pc_point_make(schema);
		for ( j = 0; j < ndims; j++ )
		{
			PCDIMENSION *dim = pc_schema_get_dimension(schema, j);

			uint8_t *in = pdl_uncompressed->bytes[j].bytes + dim->size * i;
			uint8_t *out = pt->data + dim->byteoffset;
			memcpy(out, in, dim->size);
		}
		pc_pointlist_add_point(pl, pt);
	}
	pc_patch_dimensional_free(pdl_uncompressed);

	return pl;
}
예제 #3
0
int
pc_point_set_double_by_index(PCPOINT *pt, uint32_t idx, double val)
{
	PCDIMENSION *d;
	d = pc_schema_get_dimension(pt->schema, idx);
	return pc_point_set_double(pt, d, val);
}
예제 #4
0
int
pc_point_get_double_by_index(const PCPOINT *pt, uint32_t idx, double *val)
{
	PCDIMENSION *dim;
	dim = pc_schema_get_dimension(pt->schema, idx);
	return pc_point_get_double(pt, dim, val);
}
예제 #5
0
int
pc_point_get_double_by_index(const PCPOINT *pt, uint32_t idx, double *d)
{
	PCDIMENSION *dim;
	dim = pc_schema_get_dimension(pt->schema, idx);
	if ( ! dim ) return PC_FAILURE;
	return pc_point_get_double(pt, dim, d);
}
예제 #6
0
/** get point n, 0-based, positive */
PCPOINT *pc_patch_dimensional_pointn(const PCPATCH_DIMENSIONAL *pdl, int n)
{
	assert(pdl);
	assert(pdl->schema);
	int i;
	int ndims = pdl->schema->ndims;
	PCPOINT *pt = pc_point_make(pdl->schema);
	uint8_t *buf = pt->data;
	for ( i = 0; i < ndims; i++ )
	{
		PCDIMENSION *dim = pc_schema_get_dimension(pdl->schema, i);
		pc_bytes_to_ptr(buf+dim->byteoffset,pdl->bytes[i], n);
	}

	return pt;
}
PCPATCH_UNCOMPRESSED *
pc_patch_uncompressed_from_dimensional(const PCPATCH_DIMENSIONAL *pdl)
{
	int i, j, npoints;
	PCPATCH_UNCOMPRESSED *patch;
	PCPATCH_DIMENSIONAL *pdl_uncompressed;
	const PCSCHEMA *schema;
	uint8_t *buf;

	npoints = pdl->npoints;
	schema = pdl->schema;
	patch = pcalloc(sizeof(PCPATCH_UNCOMPRESSED));
	patch->type = PC_NONE;
	patch->readonly = PC_FALSE;
	patch->schema = schema;
	patch->npoints = npoints;
	patch->maxpoints = npoints;
	patch->bounds = pdl->bounds;
	patch->stats = pc_stats_clone(pdl->stats);
	patch->datasize = schema->size * pdl->npoints;
	patch->data = pcalloc(patch->datasize);
	buf = patch->data;

	/* Can only read from uncompressed dimensions */
	pdl_uncompressed = pc_patch_dimensional_decompress(pdl);

	for ( i = 0; i < npoints; i++ )
	{
		for ( j = 0; j < schema->ndims; j++ )
		{
			PCDIMENSION *dim = pc_schema_get_dimension(schema, j);
			uint8_t *in = pdl_uncompressed->bytes[j].bytes + dim->size * i;
			uint8_t *out = buf + dim->byteoffset;
			memcpy(out, in, dim->size);
		}
		buf += schema->size;
	}

	pc_patch_dimensional_free(pdl_uncompressed);

	return patch;
}
예제 #8
0
PCPATCH_DIMENSIONAL *
pc_patch_dimensional_from_uncompressed(const PCPATCH_UNCOMPRESSED *pa)
{
	PCPATCH_DIMENSIONAL *pdl;
	const PCSCHEMA *schema;
	int i, j, ndims, npoints;

	assert(pa);
	npoints = pa->npoints;
	schema = pa->schema;
	ndims = schema->ndims;

	/* Cannot handle empty patches */
	if ( npoints == 0 ) return NULL;

	/* Initialize dimensional */
	pdl = pcalloc(sizeof(PCPATCH_DIMENSIONAL));
	pdl->type = PC_DIMENSIONAL;
	pdl->readonly = PC_FALSE;
	pdl->schema = schema;
	pdl->npoints = npoints;
	pdl->bounds = pa->bounds;
	pdl->stats = pc_stats_clone(pa->stats);
	pdl->bytes = pcalloc(ndims * sizeof(PCBYTES));

	for ( i = 0; i < ndims; i++ )
	{
		PCDIMENSION *dim = pc_schema_get_dimension(schema, i);
		pdl->bytes[i] = pc_bytes_make(dim, npoints);
		for ( j = 0; j < npoints; j++ )
		{
			uint8_t *to = pdl->bytes[i].bytes + dim->size * j;
			uint8_t *from = pa->data + schema->size * j + dim->byteoffset;
			memcpy(to, from, dim->size);
		}
	}
	return pdl;
}
예제 #9
0
static void
test_dimension_byteoffsets()
{
	PCDIMENSION *d;
	int i;
	int prev_byteoffset;
	int prev_size;
	int pc_size;

	for ( i = 0; i < schema->ndims; i++ )
	{
		d = pc_schema_get_dimension(schema, i);
		// printf("d=%d name='%s' size=%d byteoffset=%d\n", i, d->name, d->size, d->byteoffset);
		if ( i > 0 )
		{
			CU_ASSERT_EQUAL(prev_size, pc_size);
			CU_ASSERT_EQUAL(prev_size, d->byteoffset - prev_byteoffset);
		}
		prev_byteoffset = d->byteoffset;
		prev_size = d->size;
		pc_size = pc_interpretation_size(d->interpretation);
	}

}
예제 #10
0
PCPATCH_GHT *
pc_patch_ght_filter(const PCPATCH_GHT *patch, uint32_t dimnum, PC_FILTERTYPE filter, double val1, double val2)
{
#ifndef HAVE_LIBGHT
	pcerror("%s: libght support is not enabled", __func__);
	return NULL;
#else
	/*
	byte:     endianness (1 = NDR, 0 = XDR)
	uint32:   pcid (key to POINTCLOUD_SCHEMAS)
	uint32:   compression (0 = no compression, 1 = dimensional, 2 = GHT)
	uint32:   npoints
	uint32:   ghtsize
	uint8[]:  ghtbuffer
	*/

	GhtTreePtr tree;
	GhtTreePtr tree_filtered;
	GhtErr err;
	GhtWriterPtr writer;
	GhtArea area;
	const char *dimname;
	const PCDIMENSION *dim;
	PCPATCH_GHT *paght;
	int npoints;

	/* Echo null back */
	if ( ! patch ) return NULL;

	/* Get a tree */
	tree = ght_tree_from_pc_patch(patch);
	if ( ! tree ) pcerror("%s: call to ght_tree_from_pc_patch failed", __func__);

	/* Get dimname */
	dim = pc_schema_get_dimension(patch->schema, dimnum);
	if ( ! dim ) pcerror("%s: invalid dimension number (%d)", __func__, dimnum);
	dimname = dim->name;

	switch ( filter )
	{
		case PC_GT:
			err = ght_tree_filter_greater_than(tree, dimname, val1 > val2 ? val1 : val2, &tree_filtered);
			break;
		case PC_LT:
			err = ght_tree_filter_less_than(tree, dimname, val1 < val2 ? val1 : val2, &tree_filtered);
			break;
		case PC_EQUAL:
			err = ght_tree_filter_equal(tree, dimname, val1, &tree_filtered);
			break;
		case PC_BETWEEN:
			err = ght_tree_filter_between(tree, dimname, val1, val2, &tree_filtered);
			break;
		default:
			pcerror("%s: invalid filter type (%d)", __func__, filter);
			return NULL;
	}

	/* ght_tree_filter_* returns a tree with NULL tree element and npoints == 0 */
	/* for empty filter results (everything got filtered away) */
	if ( err != GHT_OK || ! tree_filtered )
		pcerror("%s: ght_tree_filter failed", __func__);

	/* Read numpoints left in patch */
	ght_tree_get_numpoints(tree_filtered, &(npoints));

	/* Allocate a fresh GHT patch for output */
	paght = pcalloc(sizeof(PCPATCH_GHT));
	paght->type = PC_GHT;
	paght->readonly = PC_FALSE;
	paght->schema = patch->schema;
	paght->npoints = npoints;

	/* No points, not much to do... */
	if ( ! npoints )
	{
		paght->ghtsize = 0;
		paght->ght = NULL;
	}
	else
	{
		/* Calculate bounds and save */
		if ( GHT_OK != ght_tree_get_extent(tree_filtered, &area) )
			pcerror("%s: ght_tree_get_extent failed", __func__);

		paght->bounds.xmin = area.x.min;
		paght->bounds.xmax = area.x.max;
		paght->bounds.ymin = area.y.min;
		paght->bounds.ymax = area.y.max;

		/* TODO: Replace this; need to update stats too */
		paght->stats = pc_stats_clone(patch->stats);

		/* Convert the tree to a memory buffer */
		ght_writer_new_mem(&writer);
		ght_tree_write(tree_filtered, writer);
		ght_writer_get_size(writer, &(paght->ghtsize));
		paght->ght = pcalloc(paght->ghtsize);
		ght_writer_get_bytes(writer, paght->ght);
		ght_writer_free(writer);
	}

	// ght_tree_free(tree_filtered);
	// ght_tree_free(tree);

	return paght;

#endif
}
예제 #11
0
PCPATCH_GHT *
pc_patch_ght_from_uncompressed(const PCPATCH_UNCOMPRESSED *pa)
{
#ifndef HAVE_LIBGHT
	pcerror("%s: libght support is not enabled", __func__);
	return NULL;
#else

	int i, j;
	int pointcount = 0;
	GhtSchemaPtr schema;
	GhtTreePtr tree;
	GhtCoordinate coord;
	GhtNodePtr node;
	PCPOINT pt;
	PCDIMENSION *xdim, *ydim;
	PCPATCH_GHT *paght = NULL;
	size_t pt_size = pa->schema->size;

	/* Cannot handle empty patches */
	if ( ! pa || ! pa->npoints ) return NULL;

	pt.schema = pa->schema;
	pt.readonly = PC_TRUE;

	xdim = pa->schema->dims[pa->schema->x_position];
	ydim = pa->schema->dims[pa->schema->y_position];

	schema = ght_schema_from_pc_schema(pa->schema);
	if ( ght_tree_new(schema, &tree) != GHT_OK ) {
		pcerror("ght_tree_new failed");
		return NULL;
	}

	/* Build up the tree from the points. */
	for ( i = 0; i < pa->npoints; i++ )
	{
		pt.data = pa->data + pt_size * i;
		pc_point_get_double(&pt, xdim, &(coord.x));
		pc_point_get_double(&pt, ydim, &(coord.y));

		/* Build a node from the x/y information */
		/* TODO, make resolution configurable from the schema */
		if ( ght_node_new_from_coordinate(&coord, GHT_MAX_HASH_LENGTH, &node) == GHT_OK )
		{
			unsigned int num_dims;
			ght_schema_get_num_dimensions(schema, &num_dims);
			/* Add attributes to the node */
			for ( j = 0; j < num_dims; j++ )
			{
				PCDIMENSION *dim;
				GhtDimensionPtr ghtdim;
				GhtAttributePtr attr;
				double val;

				/* Don't add X or Y as attributes, they are already embodied in the hash */
				if ( j == pa->schema->x_position || j == pa->schema->y_position )
					continue;

				dim = pc_schema_get_dimension(pa->schema, j);
				pc_point_get_double(&pt, dim, &val);

				ght_schema_get_dimension_by_index(schema, j, &ghtdim);
				ght_attribute_new_from_double(ghtdim, val, &attr);
				ght_node_add_attribute(node, attr);
			}

			/* Add the node to the tree */
			/* TODO, make duplicate handling configurable from the schema */
			if ( ght_tree_insert_node(tree, node) == GHT_OK )
			{
				pointcount++;
			}
			else
			{
				// ght_tree_free(tree);
				pcerror("ght_tree_insert_node failed");
				return NULL;
			}
		}
		else
		{
			ght_tree_free(tree);
			pcerror("ght_node_new_from_coordinate failed");
			return NULL;
		}
	}

	/* Compact the tree */
	if ( ght_tree_compact_attributes(tree) == GHT_OK )
	{
		GhtWriterPtr writer;
		paght = pcalloc(sizeof(PCPATCH_GHT));
		paght->type = PC_GHT;
		paght->readonly = PC_FALSE;
		paght->schema = pa->schema;
		paght->npoints = pointcount;
		paght->bounds = pa->bounds;
		paght->stats = pc_stats_clone(pa->stats);

		/* Convert the tree to a memory buffer */
		ght_writer_new_mem(&writer);
		ght_tree_write(tree, writer);
		ght_writer_get_size(writer, &(paght->ghtsize));
		paght->ght = pcalloc(paght->ghtsize);
		ght_writer_get_bytes(writer, paght->ght);
		ght_writer_free(writer);
	}

	// Let the hierarchical memory manager clean up the tree
	// ght_tree_free(tree);
	return paght;
#endif
}