Beispiel #1
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;
}
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
}