mirror of
https://github.com/pgpointcloud/pointcloud.git
synced 2025-12-08 20:36:04 +00:00
Add in schema check for validity
to pointclound metadata table
This commit is contained in:
parent
e8a7788d00
commit
06a256616d
@ -24,6 +24,9 @@ clean:
|
||||
@rm -f $(OBJS) $(LIBPC_A)
|
||||
$(MAKE) -C cunit $@
|
||||
|
||||
install:
|
||||
@echo "No install target in libpc"
|
||||
|
||||
check:
|
||||
$(MAKE) -C cunit $@
|
||||
|
||||
|
||||
@ -20,8 +20,9 @@ static int
|
||||
init_suite(void)
|
||||
{
|
||||
char *xmlstr = file_to_str(xmlfile);
|
||||
schema = pc_schema_from_xml(xmlstr);
|
||||
int rv = pc_schema_from_xml(xmlstr, &schema);
|
||||
pcfree(xmlstr);
|
||||
if ( rv == PC_FAILURE ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ static void
|
||||
test_schema_from_xml()
|
||||
{
|
||||
char *xmlstr = file_to_str(xmlfile);
|
||||
schema = pc_schema_from_xml(xmlstr);
|
||||
int rv = pc_schema_from_xml(xmlstr, &schema);
|
||||
pcfree(xmlstr);
|
||||
|
||||
// char *schemastr = pc_schema_to_json(schema);
|
||||
|
||||
@ -188,7 +188,7 @@ void pc_install_default_handlers(void);
|
||||
/** Release the memory in a schema structure */
|
||||
void pc_schema_free(PCSCHEMA *pcs);
|
||||
/** Build a schema structure from the XML serialisation */
|
||||
PCSCHEMA* pc_schema_from_xml(const char *xmlstr);
|
||||
int pc_schema_from_xml(const char *xmlstr, PCSCHEMA **schema);
|
||||
/** Print out JSON readable format of schema */
|
||||
char* pc_schema_to_json(const PCSCHEMA *pcs);
|
||||
/** Extract dimension information by position */
|
||||
|
||||
@ -198,7 +198,8 @@ pc_schema_calculate_byteoffsets(const PCSCHEMA *pcs)
|
||||
}
|
||||
|
||||
/** Population a PCSCHEMA struct from the XML representation */
|
||||
PCSCHEMA* pc_schema_from_xml(const char *xml_str)
|
||||
int
|
||||
pc_schema_from_xml(const char *xml_str, PCSCHEMA **schema)
|
||||
{
|
||||
xmlDocPtr xml_doc = NULL;
|
||||
xmlNodePtr xml_root = NULL;
|
||||
@ -206,18 +207,27 @@ PCSCHEMA* pc_schema_from_xml(const char *xml_str)
|
||||
xmlXPathContextPtr xpath_ctx;
|
||||
xmlXPathObjectPtr xpath_obj;
|
||||
xmlNodeSetPtr nodes;
|
||||
PCSCHEMA *s = NULL;
|
||||
PCSCHEMA *s;
|
||||
const char *xml_ptr = xml_str;
|
||||
|
||||
size_t xml_size = strlen(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";
|
||||
|
||||
/* Parse XML doc */
|
||||
*schema = NULL;
|
||||
xmlInitParser();
|
||||
xml_doc = xmlReadMemory(xml_str, xml_size, NULL, NULL, 0);
|
||||
xml_doc = xmlReadMemory(xml_ptr, xml_size, NULL, NULL, 0);
|
||||
if ( ! xml_doc )
|
||||
{
|
||||
xmlCleanupParser();
|
||||
pcerror("unable to parse schema XML");
|
||||
pcwarn("unable to parse schema XML");
|
||||
return PC_FAILURE;
|
||||
}
|
||||
|
||||
/* Capture the namespace */
|
||||
@ -231,7 +241,8 @@ PCSCHEMA* pc_schema_from_xml(const char *xml_str)
|
||||
{
|
||||
xmlFreeDoc(xml_doc);
|
||||
xmlCleanupParser();
|
||||
pcerror("unable to create new XPath context to read schema XML");
|
||||
pcwarn("unable to create new XPath context to read schema XML");
|
||||
return PC_FAILURE;
|
||||
}
|
||||
|
||||
/* Register the root namespace if there is one */
|
||||
@ -245,7 +256,8 @@ PCSCHEMA* pc_schema_from_xml(const char *xml_str)
|
||||
xmlXPathFreeContext(xpath_ctx);
|
||||
xmlFreeDoc(xml_doc);
|
||||
xmlCleanupParser();
|
||||
pcerror("unable to evaluate xpath expression \"%s\" against schema XML", xpath_str);
|
||||
pcwarn("unable to evaluate xpath expression \"%s\" against schema XML", xpath_str);
|
||||
return PC_FAILURE;
|
||||
}
|
||||
|
||||
/* Iterate on the dimensions we found */
|
||||
@ -254,6 +266,7 @@ PCSCHEMA* pc_schema_from_xml(const char *xml_str)
|
||||
int ndims = nodes->nodeNr;
|
||||
int i;
|
||||
s = pc_schema_new(ndims);
|
||||
*schema = s;
|
||||
|
||||
for ( i = 0; i < ndims; i++ )
|
||||
{
|
||||
@ -312,7 +325,9 @@ PCSCHEMA* pc_schema_from_xml(const char *xml_str)
|
||||
xmlXPathFreeContext(xpath_ctx);
|
||||
xmlFreeDoc(xml_doc);
|
||||
xmlCleanupParser();
|
||||
pcerror("schema dimension at position \"%d\" is declared twice", d->position + 1, ndims);
|
||||
pc_schema_free(s);
|
||||
pcwarn("schema dimension at position \"%d\" is declared twice", d->position + 1, ndims);
|
||||
return PC_FAILURE;
|
||||
}
|
||||
s->dims[d->position] = d;
|
||||
d->size = pc_interpretation_size(d->interpretation);
|
||||
@ -323,7 +338,13 @@ PCSCHEMA* pc_schema_from_xml(const char *xml_str)
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -338,7 +359,7 @@ PCSCHEMA* pc_schema_from_xml(const char *xml_str)
|
||||
xmlFreeDoc(xml_doc);
|
||||
xmlCleanupParser();
|
||||
|
||||
return s;
|
||||
return PC_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
||||
@ -48,15 +48,15 @@ Datum PC_SchemaIsValid(PG_FUNCTION_ARGS)
|
||||
bool valid;
|
||||
text *xml = PG_GETARG_TEXT_P(0);
|
||||
char *xmlstr = text_to_cstring(xml);
|
||||
PCSCHEMA *schema = pc_schema_from_xml(xmlstr);
|
||||
PCSCHEMA *schema;
|
||||
int err = pc_schema_from_xml(xmlstr, &schema);
|
||||
pfree(xmlstr);
|
||||
|
||||
if ( ! schema )
|
||||
if ( ! err )
|
||||
{
|
||||
elog(NOTICE, "pc_schema_from_xml returned NULL");
|
||||
PG_RETURN_BOOL(FALSE);
|
||||
}
|
||||
|
||||
|
||||
valid = pc_schema_is_valid(schema);
|
||||
PG_RETURN_BOOL(valid);
|
||||
}
|
||||
|
||||
@ -136,11 +136,12 @@ pc_get_schema_by_id(uint32_t pcid)
|
||||
SPI_finish();
|
||||
|
||||
/* Build the schema object */
|
||||
schema = pc_schema_from_xml(xml);
|
||||
err = pc_schema_from_xml(xml, &schema);
|
||||
|
||||
if ( ! schema )
|
||||
if ( ! err )
|
||||
{
|
||||
elog(ERROR, "unable to parse XML representation of schema");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return schema;
|
||||
|
||||
@ -17,4 +17,54 @@ CREATE TABLE pointcloud_formats (
|
||||
);
|
||||
|
||||
-- Register pointcloud_formats table so the contents are included in pg_dump output
|
||||
SELECT pg_catalog.pg_extension_config_dump('pointcloud_formats', '');
|
||||
SELECT pg_catalog.pg_extension_config_dump('pointcloud_formats', '');
|
||||
|
||||
|
||||
|
||||
-- Sample data
|
||||
INSERT INTO pointcloud_formats (pcid, srid, schema) VALUES (1, 4326, '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<pc:PointCloudSchema xmlns:pc="http://pointcloud.org/schemas/PC/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<pc:dimension>
|
||||
<pc:position>1</pc:position>
|
||||
<pc:size>4</pc:size>
|
||||
<pc:description>X coordinate as a long integer. You must use the scale and offset information of the header to determine the double value.</pc:description>
|
||||
<pc:name>X</pc:name>
|
||||
<pc:interpretation>int32_t</pc:interpretation>
|
||||
<pc:scale>0.01</pc:scale>
|
||||
</pc:dimension>
|
||||
<pc:dimension>
|
||||
<pc:position>2</pc:position>
|
||||
<pc:size>4</pc:size>
|
||||
<pc:description>Y coordinate as a long integer. You must use the scale and offset information of the header to determine the double value.</pc:description>
|
||||
<pc:name>Y</pc:name>
|
||||
<pc:interpretation>int32_t</pc:interpretation>
|
||||
<pc:scale>0.01</pc:scale>
|
||||
</pc:dimension>
|
||||
<pc:dimension>
|
||||
<pc:position>3</pc:position>
|
||||
<pc:size>4</pc:size>
|
||||
<pc:description>Z coordinate as a long integer. You must use the scale and offset information of the header to determine the double value.</pc:description>
|
||||
<pc:name>Z</pc:name>
|
||||
<pc:interpretation>int32_t</pc:interpretation>
|
||||
<pc:scale>0.01</pc:scale>
|
||||
</pc:dimension>
|
||||
<pc:dimension>
|
||||
<pc:position>4</pc:position>
|
||||
<pc:size>2</pc:size>
|
||||
<pc:description>The intensity value is the integer representation of the pulse return magnitude. This value is optional and system specific. However, it should always be included if available.</pc:description>
|
||||
<pc:name>Intensity</pc:name>
|
||||
<pc:interpretation>uint16_t</pc:interpretation>
|
||||
<pc:scale>1</pc:scale>
|
||||
</pc:dimension>
|
||||
<pc:metadata>
|
||||
<Metadata name="compression"></Metadata>
|
||||
<Metadata name="ght_xmin"></Metadata>
|
||||
<Metadata name="ght_ymin"></Metadata>
|
||||
<Metadata name="ght_xmax"></Metadata>
|
||||
<Metadata name="ght_ymax"></Metadata>
|
||||
<Metadata name="ght_keylength"></Metadata>
|
||||
<Metadata name="ght_depth"></Metadata>
|
||||
<Metadata name="spatialreference" type="id" authority="EPSG">4326</Metadata>
|
||||
</pc:metadata>
|
||||
</pc:PointCloudSchema>
|
||||
');
|
||||
Loading…
x
Reference in New Issue
Block a user