mirror of
https://github.com/pgpointcloud/pointcloud.git
synced 2025-12-08 20:36:04 +00:00
geometry cast of pcpoint with optional srid, z and m values, using caching of Z and M positions in schema.
This commit is contained in:
parent
9f19f32536
commit
165d9ea7be
@ -171,6 +171,8 @@ test_schema_clone(void)
|
||||
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->z_position, schema->z_position);
|
||||
CU_ASSERT_EQUAL(clone->m_position, schema->m_position);
|
||||
CU_ASSERT_EQUAL(clone->compression, schema->compression);
|
||||
CU_ASSERT(clone->dims != schema->dims); /* deep clone */
|
||||
CU_ASSERT(clone->namehash != schema->namehash); /* deep clone */
|
||||
|
||||
22
lib/pc_api.h
22
lib/pc_api.h
@ -88,8 +88,10 @@ typedef struct
|
||||
size_t size; /* How wide (bytes) is a point with this schema? */
|
||||
PCDIMENSION **dims; /* Array of dimension pointers */
|
||||
uint32_t srid; /* Foreign key reference to SPATIAL_REF_SYS */
|
||||
int32_t x_position; /* What entry is the x coordinate at? */
|
||||
int32_t y_position; /* What entry is the y coordinate at? */
|
||||
int32_t x_position; /* What entry is the x coordinate at? */
|
||||
int32_t y_position; /* What entry is the y coordinate at? */
|
||||
int32_t z_position; /* What entry is the z coordinate at? */
|
||||
int32_t m_position; /* What entry is the m coordinate at? */
|
||||
uint32_t compression; /* Compression type applied to the data */
|
||||
hashtable *namehash; /* Look-up from dimension name to pointer */
|
||||
} PCSCHEMA;
|
||||
@ -283,8 +285,8 @@ uint32_t pc_schema_is_valid(const PCSCHEMA *s);
|
||||
PCSCHEMA* pc_schema_clone(const PCSCHEMA *s);
|
||||
/** Add/overwrite a dimension in a schema */
|
||||
void pc_schema_set_dimension(PCSCHEMA *s, PCDIMENSION *d);
|
||||
/** Check/set the x/y position in the dimension list */
|
||||
void pc_schema_check_xy(PCSCHEMA *s);
|
||||
/** Check/set the xyzm positions in the dimension list */
|
||||
void pc_schema_check_xyzm(PCSCHEMA *s);
|
||||
/** Get the width in bytes of a single point in the schema */
|
||||
size_t pc_schema_get_size(const PCSCHEMA *s);
|
||||
|
||||
@ -344,12 +346,24 @@ double pc_point_get_x(const PCPOINT *pt);
|
||||
/** Returns Y coordinate */
|
||||
double pc_point_get_y(const PCPOINT *pt);
|
||||
|
||||
/** Returns Z coordinate */
|
||||
double pc_point_get_z(const PCPOINT *pt);
|
||||
|
||||
/** Returns M coordinate */
|
||||
double pc_point_get_m(const PCPOINT *pt);
|
||||
|
||||
/** Set the X coordinate */
|
||||
double pc_point_set_x(PCPOINT *pt, double val);
|
||||
|
||||
/** Set the Y coordinate */
|
||||
double pc_point_set_y(PCPOINT *pt, double val);
|
||||
|
||||
/** Set the Z coordinate */
|
||||
double pc_point_set_z(PCPOINT *pt, double val);
|
||||
|
||||
/** Set the M coordinate */
|
||||
double pc_point_set_m(PCPOINT *pt, double val);
|
||||
|
||||
/** Create a new readwrite PCPOINT from a hex byte array */
|
||||
PCPOINT* pc_point_from_wkb(const PCSCHEMA *s, uint8_t *wkb, size_t wkbsize);
|
||||
|
||||
|
||||
@ -154,6 +154,22 @@ pc_point_get_y(const PCPOINT *pt)
|
||||
return d;
|
||||
}
|
||||
|
||||
double
|
||||
pc_point_get_z(const PCPOINT *pt)
|
||||
{
|
||||
double d;
|
||||
pc_point_get_double_by_index(pt, pt->schema->z_position, &d);
|
||||
return d;
|
||||
}
|
||||
|
||||
double
|
||||
pc_point_get_m(const PCPOINT *pt)
|
||||
{
|
||||
double d;
|
||||
pc_point_get_double_by_index(pt, pt->schema->m_position, &d);
|
||||
return d;
|
||||
}
|
||||
|
||||
double
|
||||
pc_point_set_x(PCPOINT *pt, double val)
|
||||
{
|
||||
@ -166,6 +182,18 @@ pc_point_set_y(PCPOINT *pt, double val)
|
||||
return pc_point_set_double_by_index(pt, pt->schema->y_position, val);
|
||||
}
|
||||
|
||||
double
|
||||
pc_point_set_z(PCPOINT *pt, double val)
|
||||
{
|
||||
return pc_point_set_double_by_index(pt, pt->schema->z_position, val);
|
||||
}
|
||||
|
||||
double
|
||||
pc_point_set_m(PCPOINT *pt, double val)
|
||||
{
|
||||
return pc_point_set_double_by_index(pt, pt->schema->m_position, val);
|
||||
}
|
||||
|
||||
char *
|
||||
pc_point_to_string(const PCPOINT *pt)
|
||||
{
|
||||
@ -293,32 +321,32 @@ uint8_t *
|
||||
pc_point_to_geometry_wkb(const PCPOINT *pt, size_t *wkbsize)
|
||||
{
|
||||
static uint32_t srid_mask = 0x20000000;
|
||||
static uint32_t m_mask = 0x40000000;
|
||||
static uint32_t z_mask = 0x80000000;
|
||||
uint32_t wkbtype = 1; /* WKB POINT */
|
||||
size_t size = 1 + 4 + 8 + 8; /* endian + type + dblX, + dblY */
|
||||
uint8_t *wkb, *ptr;
|
||||
uint32_t srid;
|
||||
int has_srid = PC_FALSE, has_z = PC_FALSE;
|
||||
double x, y, z;
|
||||
uint32_t srid = pt->schema->srid;
|
||||
double x, y, z, m;
|
||||
|
||||
x = pc_point_get_x(pt);
|
||||
y = pc_point_get_y(pt);
|
||||
|
||||
if ( pt->schema->srid > 0 )
|
||||
if ( srid != 0 )
|
||||
{
|
||||
has_srid = PC_TRUE;
|
||||
wkbtype |= srid_mask;
|
||||
size += 4;
|
||||
srid = pt->schema->srid;
|
||||
}
|
||||
|
||||
if ( pc_point_get_double_by_name(pt, "Z", &z) )
|
||||
if ( pt->schema->z_position > -1 )
|
||||
{
|
||||
has_z = PC_TRUE;
|
||||
wkbtype |= z_mask;
|
||||
size += 8;
|
||||
}
|
||||
|
||||
if ( pt->schema->m_position > -1 )
|
||||
{
|
||||
wkbtype |= m_mask;
|
||||
size += 8;
|
||||
}
|
||||
|
||||
wkb = pcalloc(size);
|
||||
ptr = wkb;
|
||||
|
||||
@ -328,24 +356,34 @@ pc_point_to_geometry_wkb(const PCPOINT *pt, size_t *wkbsize)
|
||||
memcpy(ptr, &wkbtype, 4); /* WKB type */
|
||||
ptr += 4;
|
||||
|
||||
if ( has_srid )
|
||||
if ( srid != 0 )
|
||||
{
|
||||
memcpy(ptr, &srid, 4); /* SRID */
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
x = pc_point_get_x(pt);
|
||||
memcpy(ptr, &x, 8); /* X */
|
||||
ptr += 8;
|
||||
|
||||
y = pc_point_get_y(pt);
|
||||
memcpy(ptr, &y, 8); /* Y */
|
||||
ptr += 8;
|
||||
|
||||
if ( has_z )
|
||||
if ( pt->schema->z_position > -1 )
|
||||
{
|
||||
z = pc_point_get_z(pt);
|
||||
memcpy(ptr, &z, 8); /* Z */
|
||||
ptr += 8;
|
||||
}
|
||||
|
||||
if ( pt->schema->m_position > -1 )
|
||||
{
|
||||
m = pc_point_get_z(pt);
|
||||
memcpy(ptr, &m, 8); /* M */
|
||||
ptr += 8;
|
||||
}
|
||||
|
||||
if ( wkbsize ) *wkbsize = size;
|
||||
return wkb;
|
||||
}
|
||||
|
||||
@ -198,6 +198,8 @@ pc_schema_new(uint32_t ndims)
|
||||
pcs->ndims = ndims;
|
||||
pcs->x_position = -1;
|
||||
pcs->y_position = -1;
|
||||
pcs->z_position = -1;
|
||||
pcs->m_position = -1;
|
||||
return pcs;
|
||||
}
|
||||
|
||||
@ -237,6 +239,8 @@ pc_schema_clone(const PCSCHEMA *s)
|
||||
pcs->srid = s->srid;
|
||||
pcs->x_position = s->x_position;
|
||||
pcs->y_position = s->y_position;
|
||||
pcs->z_position = s->z_position;
|
||||
pcs->m_position = s->m_position;
|
||||
pcs->compression = s->compression;
|
||||
for ( i = 0; i < pcs->ndims; i++ )
|
||||
{
|
||||
@ -326,7 +330,7 @@ pc_schema_to_json(const PCSCHEMA *pcs)
|
||||
return str;
|
||||
}
|
||||
|
||||
void pc_schema_check_xy(PCSCHEMA *s)
|
||||
void pc_schema_check_xyzm(PCSCHEMA *s)
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < s->ndims; i++ )
|
||||
@ -347,17 +351,32 @@ void pc_schema_check_xy(PCSCHEMA *s)
|
||||
s->y_position = i;
|
||||
continue;
|
||||
}
|
||||
if ( strcasecmp(dimname, "Z") == 0 ||
|
||||
strcasecmp(dimname, "H") == 0 ||
|
||||
strcasecmp(dimname, "Height") == 0 )
|
||||
{
|
||||
s->z_position = i;
|
||||
continue;
|
||||
}
|
||||
if ( strcasecmp(dimname, "M") == 0 ||
|
||||
strcasecmp(dimname, "T") == 0 ||
|
||||
strcasecmp(dimname, "Time") == 0 ||
|
||||
strcasecmp(dimname, "GPSTime") == 0 )
|
||||
{
|
||||
s->m_position = i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( s->x_position < 0 )
|
||||
{
|
||||
pcerror("pc_schema_check_xy: invalid x_position '%d'", s->x_position);
|
||||
pcerror("pc_schema_check_xyzm: invalid x_position '%d'", s->x_position);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( s->y_position < 0 )
|
||||
{
|
||||
pcerror("pc_schema_check_xy: invalid y_position '%d'", s->y_position);
|
||||
pcerror("pc_schema_check_xyzm: invalid y_position '%d'", s->y_position);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -461,7 +480,6 @@ pc_schema_from_xml(const char *xml_str, PCSCHEMA **schema)
|
||||
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 )
|
||||
@ -471,21 +489,7 @@ pc_schema_from_xml(const char *xml_str, PCSCHEMA **schema)
|
||||
char *content = (char*)(child->children->content);
|
||||
char *name = (char*)(child->name);
|
||||
if ( strcmp(name, "name") == 0 )
|
||||
{
|
||||
if ( strcasecmp(content, "X") == 0 ||
|
||||
strcasecmp(content, "Longitude") == 0 ||
|
||||
strcasecmp(content, "Lon") == 0 )
|
||||
{
|
||||
xydim = 'x';
|
||||
}
|
||||
if ( strcasecmp(content, "Y") == 0 ||
|
||||
strcasecmp(content, "Latitude") == 0 ||
|
||||
strcasecmp(content, "Lat") == 0 )
|
||||
{
|
||||
xydim = 'y';
|
||||
}
|
||||
d->name = pcstrdup(content);
|
||||
}
|
||||
else if ( strcmp(name, "description") == 0 )
|
||||
d->description = pcstrdup(content);
|
||||
else if ( strcmp(name, "size") == 0 )
|
||||
@ -525,14 +529,6 @@ pc_schema_from_xml(const char *xml_str, PCSCHEMA **schema)
|
||||
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
|
||||
@ -550,8 +546,8 @@ pc_schema_from_xml(const char *xml_str, PCSCHEMA **schema)
|
||||
|
||||
/* Complete the byte offsets of dimensions from the ordered sizes */
|
||||
pc_schema_calculate_byteoffsets(s);
|
||||
/* Check X/Y positions */
|
||||
pc_schema_check_xy(s);
|
||||
/* Check XYZM positions */
|
||||
pc_schema_check_xyzm(s);
|
||||
}
|
||||
|
||||
xmlXPathFreeObject(xpath_obj);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user