Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/cunit/cu_pc_schema.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -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 */
Expand Down
22 changes: 18 additions & 4 deletions lib/pc_api.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -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;
Expand DownExpand Up@@ -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);

Expand DownExpand Up@@ -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);

Expand Down
64 changes: 51 additions & 13 deletions lib/pc_point.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -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)
{
Expand All@@ -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)
{
Expand DownExpand Up@@ -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;

x = pc_point_get_x(pt);
y = pc_point_get_y(pt);
uint32_t srid = pt->schema->srid;
double x, y, z, m;

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;

Expand All@@ -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;
}
Expand Down
52 changes: 24 additions & 28 deletions lib/pc_schema.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -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;
}

Expand DownExpand Up@@ -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++ )
{
Expand DownExpand Up@@ -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++ )
Expand All@@ -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;
}
}
Expand DownExpand Up@@ -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 )
Expand All@@ -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 )
Expand DownExpand Up@@ -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
Expand All@@ -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);
Expand Down