Пример #1
0
static GhtErr
l2g_save_tree(const Las2GhtConfig *config, Las2GhtState *state, const GhtTreePtr tree)
{
    char ght_filename[STRSIZE];
    char xml_filename[STRSIZE];
    GhtWriterPtr writer;
    GhtSchemaPtr schema;
    GhtHash *hash = NULL;

    assert(config);
    assert(state);
    assert(tree);

    ght_tree_get_hash(tree, &hash);

    l2g_ght_file(config, state, hash, ght_filename);
    l2g_xml_file(config, state, hash, xml_filename);

    ght_info("writing tree to file %s", ght_filename);

    if ( ! l2g_writable(ght_filename) )
    {
        ght_error("unable to write to '%s'", ght_filename);
        return GHT_ERROR;
    }
    if ( ! l2g_writable(xml_filename) )
    {
        ght_error("unable to write to '%s'", xml_filename);
        return GHT_ERROR;
    }

    GHT_TRY(ght_tree_get_schema(tree, &schema));
    GHT_TRY(ght_schema_to_xml_file(schema, xml_filename));
    GHT_TRY(ght_writer_new_file(ght_filename, &writer));
    GHT_TRY(ght_tree_write(tree, writer));
    GHT_TRY(ght_writer_free(writer));
    
    /* Increment file counter */
    state->fileno++;

    return GHT_OK;
}
Пример #2
0
static void
test_ght_node_file_serialization(void)
{
    GhtCoordinate coord;
    GhtNode *node, *root, *noderead;
    GhtErr err;
    GhtWriter *writer;
    GhtReader *reader;
    stringbuffer_t *sb1;
    GhtAttribute *attr;
    const char* testfile = "test.ght";

    if ( fexists(testfile) )
        remove(testfile);

    coord.x = -127.4123;
    coord.y = 49.23141;
    err = ght_node_new_from_coordinate(&coord, GHT_MAX_HASH_LENGTH, &node);
    CU_ASSERT_EQUAL(err, GHT_OK);
    root = node;
    
    coord.x = -127.4122;
    coord.y = 49.23142;
    err = ght_node_new_from_coordinate(&coord, GHT_MAX_HASH_LENGTH, &node);
    err = ght_attribute_new_from_double(schema->dims[2], 88.88, &attr);
    err = ght_node_add_attribute(node, attr);
    err = ght_node_insert_node(root, node, GHT_DUPES_YES);
    CU_ASSERT_EQUAL(err, GHT_OK);

    coord.x = -127.4122001;
    coord.y = 49.23142001;
    err = ght_node_new_from_coordinate(&coord, GHT_MAX_HASH_LENGTH, &node);
    err = ght_attribute_new_from_double(schema->dims[2], 15.23, &attr);
    err = ght_node_add_attribute(node, attr);
    err = ght_node_insert_node(root, node, GHT_DUPES_YES);
    CU_ASSERT_EQUAL(err, GHT_OK);

    coord.x = -127.4122002;
    coord.y = 49.23142002;
    err = ght_node_new_from_coordinate(&coord, GHT_MAX_HASH_LENGTH, &node);
    err = ght_attribute_new_from_double(schema->dims[2], 19.23, &attr);
    err = ght_node_add_attribute(node, attr);
    err = ght_node_insert_node(root, node, GHT_DUPES_YES);
    CU_ASSERT_EQUAL(err, GHT_OK);
    
    // sb1 = stringbuffer_create();
    // err = ght_node_to_string(root, sb1, 0);
    // printf("\n%s\n", stringbuffer_getstring(sb1));
    // stringbuffer_destroy(sb1);
    
    err = ght_writer_new_file(testfile, &writer);
    CU_ASSERT_EQUAL(err, GHT_OK);
    err = ght_node_write(root, writer);
    CU_ASSERT_EQUAL(err, GHT_OK);
    ght_writer_free(writer);
    
    err = ght_reader_new_file(testfile, schema, &reader);
    CU_ASSERT_EQUAL(err, GHT_OK);
    err = ght_node_read(reader, &noderead);
    CU_ASSERT_EQUAL(err, GHT_OK);
    ght_reader_free(reader);
    remove(testfile);

    ght_node_free(root);
    ght_node_free(noderead);
    
}
Пример #3
0
static void
test_ght_node_serialization(void)
{
    GhtCoordinate coord;
    int x, y;
    GhtNode *node1, *node2, *node3;
    GhtErr err;
    GhtWriter *writer;
    GhtReader *reader;
    const uint8_t *bytes;
    size_t bytes_size;
    stringbuffer_t *sb1, *sb2;
    GhtAttribute *attr;
    char *hex;

    /* ght_node_new_from_coordinate(const GhtCoordinate *coord, unsigned int resolution, GhtNode **node); */
    coord.x = -127.4123;
    coord.y = 49.23141;
    err = ght_node_new_from_coordinate(&coord, GHT_MAX_HASH_LENGTH, &node1);
    CU_ASSERT_STRING_EQUAL(node1->hash, "c0v2hdm1wpzpy4vtv4");
    CU_ASSERT_EQUAL(err, GHT_OK);

    err = ght_writer_new_mem(&writer);
    err = ght_node_write(node1, writer);
    bytes = bytebuffer_getbytes(writer->bytebuffer);
    bytes_size = bytebuffer_getsize(writer->bytebuffer);
    err = ght_reader_new_mem(bytes, bytes_size, schema, &reader);
    err = ght_node_read(reader, &node2);
    
    CU_ASSERT_STRING_EQUAL(node1->hash, node2->hash);
    ght_node_free(node2);

    /* add a child */
    coord.x = -127.4125;
    coord.y = 49.23144;
    err = ght_node_new_from_coordinate(&coord, GHT_MAX_HASH_LENGTH, &node3);
    err = ght_attribute_new_from_double(schema->dims[3], 88.88, &attr);
    err = ght_node_add_attribute(node3, attr);
    err = ght_node_insert_node(node1, node3, GHT_DUPES_YES);
    CU_ASSERT_EQUAL(err, GHT_OK);

    /* add another (dupe) child */
    err = ght_node_new_from_coordinate(&coord, GHT_MAX_HASH_LENGTH, &node3);
    err = ght_node_insert_node(node1, node3, GHT_DUPES_YES);

    /* add another (dupe) child with an attribute */
    err = ght_node_new_from_coordinate(&coord, GHT_MAX_HASH_LENGTH, &node3);
    err = ght_attribute_new_from_double(schema->dims[2], 99.99, &attr);
    err = ght_node_add_attribute(node3, attr);
    err = ght_node_insert_node(node1, node3, GHT_DUPES_YES);
    
    sb1 = stringbuffer_create();
    err = ght_node_to_string(node1, sb1, 0);
    // printf("ORIGINAL\n%s\n", stringbuffer_getstring(sb1));

    err = ght_writer_new_mem(&writer);
    err = ght_node_write(node1, writer);
    bytes = bytebuffer_getbytes(writer->bytebuffer);
    bytes_size = bytebuffer_getsize(writer->bytebuffer);

    err = hexbytes_from_bytes(bytes, bytes_size, &hex);
    CU_ASSERT_STRING_EQUAL("086330763268646D3100020A77707A7079347674763400000A6374643463637839796201035800020000000001020F27000000", hex);
    // printf("\n\n%s\n", hex);
    
    err = ght_reader_new_mem(bytes, bytes_size, schema, &reader);
    err = ght_node_read(reader, &node2);
    
    sb2 = stringbuffer_create();
    err = ght_node_to_string(node2, sb2, 0);
    // printf("COPY\n%s\n", stringbuffer_getstring(sb2));
    
    CU_ASSERT_STRING_EQUAL(stringbuffer_getstring(sb1), stringbuffer_getstring(sb2));
    stringbuffer_destroy(sb2);
    stringbuffer_destroy(sb1);
    ght_node_free(node1);
    ght_node_free(node2);
    ght_writer_free(writer);
    ght_reader_free(reader);
}
Пример #4
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
}
Пример #5
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
}