static int
clean_suite(void)
{
	pc_schema_free(simpleschema);
	pc_schema_free(multipledimschema);
	return 0;
}
Beispiel #2
0
static int
clean_suite(void)
{
	pc_schema_free(schema);
	pc_schema_free(simpleschema);
	pc_schema_free(lasschema);
	return 0;
}
Beispiel #3
0
static void
test_schema_clone(void)
{
    int i;
    PCSCHEMA *myschema;
    PCSCHEMA *clone = pc_schema_clone(schema);
    hashtable *hash, *chash;
    char *xmlstr;
    CU_ASSERT_EQUAL(clone->pcid, schema->pcid);
    CU_ASSERT_EQUAL(clone->ndims, schema->ndims);
    CU_ASSERT_EQUAL(clone->size, schema->size);
    CU_ASSERT_EQUAL(clone->srid, schema->srid);
    CU_ASSERT_EQUAL(clone->x_position, schema->x_position);
    CU_ASSERT_EQUAL(clone->y_position, schema->y_position);
    CU_ASSERT_EQUAL(clone->compression, schema->compression);
    CU_ASSERT(clone->dims != schema->dims); /* deep clone */
    CU_ASSERT(clone->namehash != schema->namehash); /* deep clone */
    hash = schema->namehash;
    chash = clone->namehash;
    CU_ASSERT_EQUAL(chash->tablelength, hash->tablelength);
    CU_ASSERT_EQUAL(chash->entrycount, hash->entrycount);
    CU_ASSERT_EQUAL(chash->loadlimit, hash->loadlimit);
    CU_ASSERT_EQUAL(chash->primeindex, hash->primeindex);
    CU_ASSERT_EQUAL(chash->hashfn, hash->hashfn);
    CU_ASSERT_EQUAL(chash->eqfn, hash->eqfn);
    CU_ASSERT(chash->table != hash->table); /* deep clone */
    for (i=0; i<schema->ndims; ++i) {
      PCDIMENSION *dim = schema->dims[i];
      PCDIMENSION *cdim = clone->dims[i];
      CU_ASSERT(dim != cdim); /* deep clone */
      CU_ASSERT_STRING_EQUAL(cdim->name, dim->name);
      CU_ASSERT_STRING_EQUAL(cdim->description, dim->description);
      CU_ASSERT_EQUAL(cdim->position, dim->position);
      CU_ASSERT_EQUAL(cdim->size, dim->size);
      CU_ASSERT_EQUAL(cdim->byteoffset, dim->byteoffset);
      CU_ASSERT_EQUAL(cdim->interpretation, dim->interpretation);
      CU_ASSERT_EQUAL(cdim->scale, dim->scale);
      CU_ASSERT_EQUAL(cdim->offset, dim->offset);
      CU_ASSERT_EQUAL(cdim->active, dim->active);
      /* hash table is correctly setup */
      CU_ASSERT_EQUAL(cdim, hashtable_search(clone->namehash, dim->name) );
    }

    pc_schema_free(clone);

    /* See https://github.com/pgpointcloud/pointcloud/issues/66 */
	  xmlstr = "<pc:PointCloudSchema xmlns:pc='x'><pc:dimension><pc:position>1</pc:position></pc:dimension></pc:PointCloudSchema>";
    i = pc_schema_from_xml(xmlstr, &myschema);
	  CU_ASSERT_EQUAL(i, PC_SUCCESS);
    clone = pc_schema_clone(myschema);
    CU_ASSERT_EQUAL(clone->ndims, myschema->ndims);
    CU_ASSERT_EQUAL(clone->dims[0]->name, NULL);
    CU_ASSERT_EQUAL(clone->dims[0]->description, NULL);
    pc_schema_free(myschema);
    pc_schema_free(clone);
}
Beispiel #4
0
static int
clean_suite(void)
{
	pc_schema_free(schema);
	pc_schema_free(simpleschema);
	pc_schema_free(simpleschema_nointensity);
	pc_schema_free(lasschema);
	pc_schema_free(simplelazschema);
	return 0;
}
Beispiel #5
0
static int
clean_suite(void)
{
	pc_schema_free(schema);
	pc_schema_free(schema_xy);
	pc_schema_free(schema_xyz);
	pc_schema_free(schema_xym);
	pc_schema_free(schema_xyzm);
	return 0;
}
Beispiel #6
0
Datum pcpoint_from_double_array(PG_FUNCTION_ARGS)
{
	uint32 pcid = PG_GETARG_INT32(0);
	ArrayType *arrptr = PG_GETARG_ARRAYTYPE_P(1);
	int nelems;
	float8 *vals;
	PCPOINT *pt;
	PCSCHEMA *schema = pc_schema_from_pcid(pcid, fcinfo);
	SERIALIZED_POINT *serpt;

	if ( ! schema )
		elog(ERROR, "unable to load schema for pcid = %d", pcid);

	if ( ARR_ELEMTYPE(arrptr) != FLOAT8OID )
		elog(ERROR, "array must be of float8[]");
		
	if ( ARR_NDIM(arrptr) != 1 )
		elog(ERROR, "float8[] must have only one dimension");

	if ( ARR_HASNULL(arrptr) )
		elog(ERROR, "float8[] must not have null elements");
	
	nelems = ARR_DIMS(arrptr)[0];
	if ( nelems != schema->ndims || ARR_LBOUND(arrptr)[0] > 1 )
		elog(ERROR, "array dimenensions do not match schema dimensions of pcid = %d", pcid);
	
	vals = (float8*) ARR_DATA_PTR(arrptr);
    pt = pc_point_from_double_array(schema, vals, nelems);

	serpt = pc_point_serialize(pt);
	pc_point_free(pt);
	pc_schema_free(schema);
	PG_RETURN_POINTER(serpt);
}
Beispiel #7
0
Datum pcschema_get_ndims(PG_FUNCTION_ARGS)
{
	int ndims;
	uint32 pcid = PG_GETARG_INT32(0);
	PCSCHEMA *schema = pc_schema_from_pcid(pcid, fcinfo);

	if ( ! schema )
		elog(ERROR, "unable to load schema for pcid = %d", pcid);

	ndims = schema->ndims;
	pc_schema_free(schema);
	PG_RETURN_INT32(ndims);
}
static void
test_schema_compression_lazperf(void)
{
	PCSCHEMA *myschema = NULL;
	char *myxmlfile = "data/simple-schema-laz.xml";
	char *xmlstr = file_to_str(myxmlfile);
	myschema = pc_schema_from_xml(xmlstr);

	CU_ASSERT_PTR_NOT_NULL(myschema);
	int compression = myschema->compression;
	CU_ASSERT_EQUAL(compression, PC_LAZPERF);

	pc_schema_free(myschema);
	pcfree(xmlstr);
}
Beispiel #9
0
static void
test_schema_from_xml()
{
    static PCSCHEMA *myschema = NULL;
	char *xmlstr = file_to_str(xmlfile);
	int rv = pc_schema_from_xml(xmlstr, &myschema);
	pcfree(xmlstr);

	// char *schemastr = pc_schema_to_json(schema);
	// printf("ndims %d\n", schema->ndims);
	// printf("name0 %s\n", schema->dims[0]->name);
	// printf("%s\n", schemastr);

	CU_ASSERT(myschema != NULL);
    pc_schema_free(myschema);
}
Beispiel #10
0
static void
test_schema_is_valid()
{
	static PCSCHEMA *myschema = NULL;
	char *xmlstr;
	int rv;

	// See https://github.com/pgpointcloud/pointcloud/issues/28
	xmlstr = "<pc:PointCloudSchema xmlns:pc='x'><pc:dimension>1</pc:dimension></pc:PointCloudSchema>";
	rv = pc_schema_from_xml(xmlstr, &myschema);
	CU_ASSERT_EQUAL(rv, PC_SUCCESS);

  cu_error_msg_reset();
  rv = pc_schema_is_valid(myschema);
	CU_ASSERT_EQUAL(rv, PC_FAILURE);

  pc_schema_free(myschema);
}
Beispiel #11
0
Datum pcschema_is_valid(PG_FUNCTION_ARGS)
{
	bool valid;
	text *xml = PG_GETARG_TEXT_P(0);
	char *xmlstr = text_to_cstring(xml);
	PCSCHEMA *schema;
	int err = pc_schema_from_xml(xmlstr, &schema);
	pfree(xmlstr);

	if ( ! err )
	{
		PG_RETURN_BOOL(FALSE);
	}

	valid = pc_schema_is_valid(schema);
	pc_schema_free(schema);
	PG_RETURN_BOOL(valid);
}
Beispiel #12
0
static void
test_patch_set_schema_compression_none_offset()
{
	// init data
	PCPATCH_UNCOMPRESSED *pau;
	PCPATCH *pat;
	PCPOINTLIST *pl;
	PCPOINT *pt;
	PCSCHEMA *new_schema;
	char *str;
	int i;
	int npts = 4;

	// build a patch
	pl = pc_pointlist_make(npts);
	for ( i = npts; i >= 0; i-- )
	{
		pt = pc_point_make(simpleschema_nointensity);
		pc_point_set_double_by_name(pt, "X", i * 0.1);
		pc_point_set_double_by_name(pt, "Y", i * 0.2);
		pc_point_set_double_by_name(pt, "Z", i * 0.3);
		pc_pointlist_add_point(pl, pt);
	}
	pau = pc_patch_uncompressed_from_pointlist(pl);

	new_schema = pc_schema_clone(simpleschema);
	new_schema->dims[3]->offset = 10;

	// assign a valid schema to the patch
	pat = pc_patch_set_schema((PCPATCH *) pau, new_schema, 0.0);
	CU_ASSERT(pat != NULL);
	str = pc_patch_to_string(pat);
	CU_ASSERT_STRING_EQUAL(str, "{\"pcid\":0,\"pts\":[[0.4,0.8,1.2,10],[0.3,0.6,0.9,10],[0.2,0.4,0.6,10],[0.1,0.2,0.3,10],[0,0,0,10]]}");
	pcfree(str);

	pc_patch_free(pat);
	pc_schema_free(new_schema);
	pc_patch_free((PCPATCH*) pau);
	pc_pointlist_free(pl);
}
Beispiel #13
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;
}
Beispiel #14
0
static int
clean_suite(void)
{
	pc_schema_free(schema);
	return 0;
}
Beispiel #15
0
static void
test_patch_transform_compression_none()
{
	// init data
	PCPATCH_UNCOMPRESSED *pau;
	PCSCHEMA *nschema;
	PCPOINTLIST *pl;
	PCPATCH *pa;
	PCPOINT *pt;
	char *str;
	int i;
	int npts = 5;
	uint8_t *wkb;
	size_t wkbsize;

	// build a patch
	pl = pc_pointlist_make(npts);
	for ( i = (npts - 1); i >= 0; i-- )
	{
		pt = pc_point_make(simpleschema);
		pc_point_set_double_by_name(pt, "X", i * 0.1);
		pc_point_set_double_by_name(pt, "Y", i * 0.2);
		pc_point_set_double_by_name(pt, "Z", i * 0.3);
		pc_point_set_double_by_name(pt, "Intensity", 10);
		pc_pointlist_add_point(pl, pt);
	}
	pau = pc_patch_uncompressed_from_pointlist(pl);

	// create a new schema, and use 0.02 scale values for x, y and z
	nschema = pc_schema_clone(simpleschema);
	nschema->xdim->scale = 0.02;
	nschema->ydim->scale = 0.02;
	nschema->zdim->scale = 0.02;

	// transform the patch
	pa = pc_patch_transform((PCPATCH*) pau, nschema, 0.0);
	CU_ASSERT(pa != NULL);

	// check point 1
	// expected: x=hex(20)=0x14, y=hex(40)=0x28, z=hex(60)=0x3C, I=hex(10)=0x0A
	pt = pc_patch_pointn(pa, 1);
	wkb = pc_point_to_wkb(pt, &wkbsize);
	str = hexbytes_from_bytes(wkb, wkbsize);
	CU_ASSERT_STRING_EQUAL(str, "010000000014000000280000003C0000000A00");
	pcfree(str);
	pcfree(wkb);
	pc_point_free(pt);

	// check point 2
	// expected: x=hex(15)=0x0F, y=hex(30)=0x1E, z=hex(45)=0x2D, I=hex(10)=0x0A
	pt = pc_patch_pointn(pa, 2);
	wkb = pc_point_to_wkb(pt, &wkbsize);
	str = hexbytes_from_bytes(wkb, wkbsize);
	CU_ASSERT_STRING_EQUAL(str, "01000000000F0000001E0000002D0000000A00");
	pcfree(str);
	pcfree(wkb);
	pc_point_free(pt);

	// check point 3
	// expected: x=hex(10)=0x0A, y=hex(20)=0x14, z=hex(30)=0x1E, I=hex(10)=0x0A
	pt = pc_patch_pointn(pa, 3);
	wkb = pc_point_to_wkb(pt, &wkbsize);
	str = hexbytes_from_bytes(wkb, wkbsize);
	CU_ASSERT_STRING_EQUAL(str, "01000000000A000000140000001E0000000A00");
	pcfree(str);
	pcfree(wkb);
	pc_point_free(pt);

	// check point 4
	// expected: x=hex(5)=0x05, y=hex(10)=0x0A, z=hex(15)=0x0F, I=hex(10)=0x0A
	pt = pc_patch_pointn(pa, 4);
	wkb = pc_point_to_wkb(pt, &wkbsize);
	str = hexbytes_from_bytes(wkb, wkbsize);
	CU_ASSERT_STRING_EQUAL(str, "0100000000050000000A0000000F0000000A00");
	pcfree(str);
	pcfree(wkb);
	pc_point_free(pt);

	// check point 5
	// expected: x=hex(0)=0x00, y=hex(0)=0x00, z=hex(0)=0x00, I=hex(10)=0x0A
	pt = pc_patch_pointn(pa, 5);
	wkb = pc_point_to_wkb(pt, &wkbsize);
	str = hexbytes_from_bytes(wkb, wkbsize);
	CU_ASSERT_STRING_EQUAL(str, "01000000000000000000000000000000000A00");
	pcfree(str);
	pcfree(wkb);
	pc_point_free(pt);

	pc_patch_free(pa);
	pc_schema_free(nschema);
	pc_patch_free((PCPATCH*) pau);
	pc_pointlist_free(pl);
}