示例#1
0
/**
 * @param schema we want to partially clone
 * @param an array with the position of the dimension we want to *keep*
 * @param the total number of dimension we want to keep
 * @return a cloned schema with only the dimension whose position are provided, the new position of dimension is there index+1 in provided array, NULL if something wen wrong
 * */
PCSCHEMA * 
pc_schema_clone_subset(  PCSCHEMA *s, uint32_t * dimensions_position_array, uint32_t dimensions_number)
{
	
	int i;
	PCDIMENSION* temp_dim;
	PCSCHEMA *pcs = pc_schema_new(dimensions_number);
	pcs->pcid = s->pcid;
	pcs->srid = s->srid;
	
	pcs->compression = s->compression;
	
	//printf("\n for loop \n");
	for ( i = 0; i < dimensions_number; i++ )
	{
		if ( s->dims[dimensions_position_array[i]] )
		{
				temp_dim = pc_dimension_clone(s->dims[dimensions_position_array[i]]);//cloning the dimension
				temp_dim->position=i ; //changing the position so to have continuous dimension position
				
			pc_schema_set_dimension(pcs,temp_dim);
			//printf("cloning the dimension %s in new position %d",temp_dim->name,i);
		}
	}
	
	//the new x_position and y_position should be found according to where X and Y dimension are
		//looking for X and Y in dimension, to get the dimension position
	pcs->x_position=pc_schema_get_dimension_position_by_name(pcs,"x");
	pcs->y_position=pc_schema_get_dimension_position_by_name(pcs,"y");

	//pcinfo("updating schema : x_position : %d, y_position : %d",pcs->x_position,pcs->y_position);
	pc_schema_calculate_byteoffsets(pcs);

	return pcs;
}
示例#2
0
PCSCHEMA*
pc_schema_clone(const PCSCHEMA *s)
{
    int i;
    PCSCHEMA *pcs = pc_schema_new(s->ndims);
    pcs->pcid = s->pcid;
    pcs->srid = s->srid;
    pcs->x_position = s->x_position;
    pcs->y_position = s->y_position;
    pcs->compression = s->compression;
    for ( i = 0; i < pcs->ndims; i++ )
    {
        if ( s->dims[i] )
        {
            pc_schema_set_dimension(pcs, pc_dimension_clone(s->dims[i]));
        }
    }
	pc_schema_calculate_byteoffsets(pcs);
    return pcs;
}
示例#3
0
/** Population a PCSCHEMA struct from the XML representation */
int
pc_schema_from_xml(const char *xml_str, PCSCHEMA **schema)
{
	xmlDocPtr xml_doc = NULL;
	xmlNodePtr xml_root = NULL;
	xmlNsPtr xml_ns = NULL;
	xmlXPathContextPtr xpath_ctx; 
	xmlXPathObjectPtr xpath_obj; 
	xmlNodeSetPtr nodes;
	PCSCHEMA *s;
	const char *xml_ptr = xml_str;
	
	/* Roll forward to start of XML string */
	while( (*xml_ptr != '\0') && (*xml_ptr != '<') )
	{
		xml_ptr++;
	}
		
	size_t xml_size = strlen(xml_ptr);
	static xmlChar *xpath_str = "/pc:PointCloudSchema/pc:dimension";
	static xmlChar *xpath_metadata_str = "/pc:PointCloudSchema/pc:metadata/Metadata";

	
	/* Parse XML doc */
	*schema = NULL;
	xmlInitParser();
	xml_doc = xmlReadMemory(xml_ptr, xml_size, NULL, NULL, 0);
	if ( ! xml_doc )
	{
		xmlCleanupParser();
		pcwarn("unable to parse schema XML");
		return PC_FAILURE;
	}
	
	/* Capture the namespace */
	xml_root = xmlDocGetRootElement(xml_doc);
	if ( xml_root->ns )
		xml_ns = xml_root->ns;
	
	/* Create xpath evaluation context */
	xpath_ctx = xmlXPathNewContext(xml_doc);
	if( ! xpath_ctx )
	{
		xmlFreeDoc(xml_doc);
		xmlCleanupParser();
		pcwarn("unable to create new XPath context to read schema XML");
		return PC_FAILURE;
	}

	/* Register the root namespace if there is one */
	if ( xml_ns )
		xmlXPathRegisterNs(xpath_ctx, "pc", xml_ns->href);
	
	/* Evaluate xpath expression */
	xpath_obj = xmlXPathEvalExpression(xpath_str, xpath_ctx);
	if( ! xpath_obj )
	{
	    xmlXPathFreeContext(xpath_ctx); 
		xmlFreeDoc(xml_doc);
		xmlCleanupParser();
		pcwarn("unable to evaluate xpath expression \"%s\" against schema XML", xpath_str);
		return PC_FAILURE;
	}

	/* Iterate on the dimensions we found */
	if ( nodes = xpath_obj->nodesetval )
	{
		int ndims = nodes->nodeNr;
		int i;
		s = pc_schema_new(ndims);
		*schema = s;
				
		for ( i = 0; i < ndims; i++ )
		{
			/* This is a "dimension" */
			if( nodes->nodeTab[i]->type == XML_ELEMENT_NODE )
			{
				xmlNodePtr cur = nodes->nodeTab[i];
				xmlNodePtr child;
				PCDIMENSION *d = pc_dimension_new();
				char xydim = 0;
				
				/* These are the values of the dimension */
				for ( child = cur->children; child; child = child->next )
				{
					if( child->type == XML_ELEMENT_NODE )
					{
						if ( strcmp(child->name, "name") == 0 )
						{
							if ( strcasecmp(child->children->content, "X") == 0 ||
							     strcasecmp(child->children->content, "Longitude") == 0 ||
							     strcasecmp(child->children->content, "Lon") == 0 )
							{
								xydim = 'x';
							}
							if ( strcasecmp(child->children->content, "Y") == 0 ||
							     strcasecmp(child->children->content, "Latitude") == 0 ||
							     strcasecmp(child->children->content, "Lat") == 0 )
							{
								xydim = 'y';
							}
							d->name = pcstrdup(child->children->content);
						}
						else if ( strcmp(child->name, "description") == 0 )
							d->description = pcstrdup(child->children->content);
						else if ( strcmp(child->name, "size") == 0 )
							d->size = atoi(child->children->content);
						else if ( strcmp(child->name, "active") == 0 )
							d->active = atoi(child->children->content);
						else if ( strcmp(child->name, "position") == 0 )
							d->position = atoi(child->children->content) - 1;
						else if ( strcmp(child->name, "interpretation") == 0 )
							d->interpretation = pc_interpretation_number(child->children->content);
						else if ( strcmp(child->name, "scale") == 0 )
							d->scale = atof(child->children->content);
						else if ( strcmp(child->name, "offset") == 0 )
							d->offset = atof(child->children->content);
						else if ( strcmp(child->name, "uuid") == 0 )
							/* Ignore this tag for now */ 1;
						else if ( strcmp(child->name, "parent_uuid") == 0 )
							/* Ignore this tag for now */ 1;
						else
							pcinfo("unhandled schema type element \"%s\" encountered", child->name);
					}
				}
				
				/* Convert interprestation to size */
				d->size = pc_interpretation_size(d->interpretation);
				
				/* Store the dimension in the schema */
				if ( d->position >= 0 && d->position < ndims )
				{
					if ( s->dims[d->position] )
					{
						xmlXPathFreeObject(xpath_obj);
					    xmlXPathFreeContext(xpath_ctx); 
						xmlFreeDoc(xml_doc);
						xmlCleanupParser();
						pc_schema_free(s);
						pcwarn("schema dimension at position \"%d\" is declared twice", d->position + 1, ndims);
						return PC_FAILURE;
					}
					if ( xydim == 'x' ) { s->x_position = d->position; }
					if ( xydim == 'y' ) { s->y_position = d->position; }
                    pc_schema_set_dimension(s, d);
				}
				else
				{
					xmlXPathFreeObject(xpath_obj);
				    xmlXPathFreeContext(xpath_ctx); 
					xmlFreeDoc(xml_doc);
					xmlCleanupParser();
					pc_schema_free(s);
					pcwarn("schema dimension states position \"%d\", but number of XML dimensions is \"%d\"", d->position + 1, ndims);
					return PC_FAILURE;
				}
			}
		}
		
		/* Complete the byte offsets of dimensions from the ordered sizes */
		pc_schema_calculate_byteoffsets(s);
		/* Check X/Y positions */
		pc_schema_check_xy(s);
	}
	
	xmlXPathFreeObject(xpath_obj);
	
	/* SEARCH FOR METADATA ENTRIES */
	xpath_obj = xmlXPathEvalExpression(xpath_metadata_str, xpath_ctx);
	if( ! xpath_obj )
	{
	    xmlXPathFreeContext(xpath_ctx); 
		xmlFreeDoc(xml_doc);
		xmlCleanupParser();
		pcwarn("unable to evaluate xpath expression \"%s\" against schema XML", xpath_metadata_str);
		return PC_FAILURE;
	}
	
	/* Iterate on the <Metadata> we find */
	if ( nodes = xpath_obj->nodesetval )
	{
		int i;

		for ( i = 0; i < nodes->nodeNr; i++ )
		{
            char *metadata_name = "";
            char *metadata_value = "";
		    /* Read the metadata name and value from the node */
		    /* <Metadata name="somename">somevalue</Metadata> */
		    xmlNodePtr cur = nodes->nodeTab[i];
            if( cur->type == XML_ELEMENT_NODE && strcmp(cur->name, "Metadata") == 0 )
            {
                metadata_name = xmlGetProp(cur, "name");
                metadata_value = xml_node_get_content(cur);
            }
            
            /* Store the compression type on the schema */
            if ( strcmp(metadata_name, "compression") == 0 )
            {
                int compression = pc_compression_number(metadata_value);
                if ( compression >= 0 )
                {
                    s->compression = compression;
                }
            }
            xmlFree(metadata_name);
        }
	}
	
	xmlXPathFreeObject(xpath_obj);
	
    xmlXPathFreeContext(xpath_ctx); 
	xmlFreeDoc(xml_doc);
	xmlCleanupParser();
	
	return PC_SUCCESS;
}