Esempio n. 1
0
static void
test_ght_build_node_with_attributes(void)
{
    GhtAttribute *a;
    GhtCoordinate coord;
    GhtNode *node;
    stringbuffer_t *sb = stringbuffer_create();
    
    /* X, Y */
    coord.x = -127;
    coord.y = 45;
    ght_node_new_from_coordinate(&coord, 16, &node);
    /* Z */
    ght_attribute_new_from_double(simpleschema->dims[2], 1231.2, &a);
    ght_node_add_attribute(node, a);
    /* Intensity */
    ght_attribute_new_from_double(simpleschema->dims[3], 3, &a);
    ght_node_add_attribute(node, a);
    
    ght_node_to_string(node, sb, 0);
    CU_ASSERT_STRING_EQUAL("c0j8n012j80252h0  Z=1231.2:Intensity=3\n", stringbuffer_getstring(sb));
    // printf("%s\n", stringbuffer_getstring(sb));
    stringbuffer_destroy(sb);
    ght_node_free(node);
}
Esempio n. 2
0
static GhtErr
l2g_build_node(const Las2GhtConfig *config, const Las2GhtState *state, LASPointH laspoint, GhtNodePtr *node)
{
    int i;
    double z;
    GhtDimensionPtr ghtdim;
    GhtAttributePtr attribute;
    GhtCoordinate coord;
    GhtErr err;
    
    assert(config);
    assert(state->schema);
    
    /* Skip invalid points, if so configured */
    if ( config->validpoints && ! LASPoint_IsValid(laspoint) )
        return GHT_ERROR;

    coord.x = LASPoint_GetX(laspoint);
    coord.y = LASPoint_GetY(laspoint);
    
    if ( l2g_coordinate_reproject(state, &coord) != GHT_OK )
        return GHT_ERROR;
    
    if ( ght_node_new_from_coordinate(&coord, config->resolution, node) != GHT_OK )
        return GHT_ERROR;

    /* We know that 'Z' is always dimension 2 */
    z = LASPoint_GetZ(laspoint);
    GHT_TRY(ght_schema_get_dimension_by_index(state->schema, 2, &ghtdim));
    
    if ( ght_attribute_new_from_double(ghtdim, z, &attribute) != GHT_OK )
        return GHT_ERROR;

    if ( ght_node_add_attribute(*node, attribute) != GHT_OK )
        return GHT_ERROR;
    
    for ( i = 0; i < config->num_attrs; i++ )
    {
        LasAttribute lasattr = config->attrs[i];
        double val = l2g_attribute_value(laspoint, lasattr);

        /* Magic number 3: X,Y,Z are first three dimensions */
        GHT_TRY(ght_schema_get_dimension_by_index(state->schema, 3+i, &ghtdim));
        
        if ( ght_attribute_new_from_double(ghtdim, val, &attribute) != GHT_OK )
            return GHT_ERROR;

        if ( ght_node_add_attribute(*node, attribute) != GHT_OK )
            return GHT_ERROR;
    }

    return GHT_OK;
}
Esempio n. 3
0
/* 
 * Recursive compaction routine. Pulls attribute up to the highest node such that
 * all children share the attribute value.
 */
static GhtErr
ght_node_compact_attribute_with_delta(GhtNode *node, 
		const GhtDimension *dim,
		double delta,
		GhtAttribute *compacted_attribute)
{
	int i;

	/* This is an internal node, see if all the children share a value in this dimension */
	if ( node->children && node->children->num_nodes > 0 )
	{
		double minval = DBL_MAX;
		double maxval = -1 * DBL_MAX;
		double totval = 0.0;
		int node_count = 0;

		/* Figure out the range of values for this dimension in child nodes */
		for ( i = 0; i < node->children->num_nodes; i++ )
		{
			GhtAttribute attr;
			GhtErr err;
			err = ght_node_compact_attribute_with_delta(node->children->nodes[i], dim, delta, &attr);
			if ( err == GHT_OK )
			{
				double d;
				GHT_TRY(ght_attribute_get_value(&attr, &d));
				(d < minval) ? (minval = d) : 0;
				(d > maxval) ? (maxval = d) : 0;
				totval += d;
				node_count++;
			}
			else
			{
				continue;
			}
		}

		/* If the range is narrow, and we got values from all our children, compact them */
		if ( (maxval-minval) < delta && node_count == node->children->num_nodes )
		{
			double val = (minval+maxval)/2.0;
			GhtAttribute *myattr;
			for ( i = 0; i < node->children->num_nodes; i++ )
			{
				ght_node_delete_attribute(node->children->nodes[i], dim);
			}
			ght_attribute_new_from_double(dim, val, &myattr);
			memcpy(compacted_attribute, myattr, sizeof(GhtAttribute));
			ght_node_add_attribute(node, myattr);
			return GHT_OK;
		}
		return GHT_ERROR;
	}
	/* This is a leaf node, send the attribute value up to the caller */
	else
	{
		if ( ! node->attributes ) return GHT_ERROR;
		return ght_attribute_get_by_dimension(node->attributes, dim, compacted_attribute);
	}
}
Esempio n. 4
0
GhtNodeList *
tsv_file_to_node_list(const char *fname, const GhtSchema *schema)
{
    GhtNodeList *nodelist;
    char *ptr_start, *ptr_end, *tmp;
    char *filestr = file_to_str(fname);
    double dblval[16]; /* Only going to handle files 16 columns wide */
    int field_num = 0;

    if ( ! filestr ) return NULL;

    ght_nodelist_new(16, &nodelist);
    
    ptr_start = ptr_end = filestr;
    
    while( 1 ) 
    {
        if ( *ptr_end == '\t' || *ptr_end == '\n' || *ptr_end == '\0' )
        {
            char ptr_tmp = *ptr_end;
            *ptr_end = '\0';
            dblval[field_num] = atof(ptr_start);
            *ptr_end = ptr_tmp;
            ptr_start = ptr_end;
            if ( *ptr_end == '\n' || ! ptr_end ) 
            {
                int i;
                GhtCoordinate coord;
                GhtNode *node;
                
                if ( schema->num_dims != field_num + 1 )
                    return NULL;
                
                coord.x = dblval[0];
                coord.y = dblval[1];
                
                ght_node_new_from_coordinate(&coord, 16, &node);
                
                for ( i = 2; i < schema->num_dims; i++ )
                {
                    GhtAttribute *a;
                    ght_attribute_new_from_double(schema->dims[i], dblval[i], &a);
                    ght_node_add_attribute(node, a);
                }
                
                ght_nodelist_add_node(nodelist, node);
                field_num = 0;
            }
            else field_num++;
            /* All done! */
            if ( *ptr_end == '\0' ) break;
        }
        ptr_end++;
    }
    return nodelist;
}
Esempio n. 5
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);
    
}
Esempio n. 6
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);
}
Esempio n. 7
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
}