2008-05-14 17:10:19 +00:00
|
|
|
#include "../postgis_config.h"
|
|
|
|
|
2004-09-29 10:50:30 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdarg.h>
|
2006-06-01 07:07:21 +00:00
|
|
|
#include <postgres.h>
|
|
|
|
#include <fmgr.h>
|
|
|
|
#include <executor/spi.h>
|
2004-09-29 10:50:30 +00:00
|
|
|
#include "liblwgeom.h"
|
|
|
|
#include "lwgeom_pg.h"
|
2006-06-01 07:07:21 +00:00
|
|
|
|
2005-12-30 17:40:37 +00:00
|
|
|
|
|
|
|
#define PARANOIA_LEVEL 1
|
2004-09-30 11:45:40 +00:00
|
|
|
|
2006-06-01 06:58:34 +00:00
|
|
|
/*
|
|
|
|
* This is required for builds against pgsql 8.2
|
|
|
|
*/
|
|
|
|
#ifdef PG_MODULE_MAGIC
|
|
|
|
PG_MODULE_MAGIC;
|
|
|
|
#endif
|
|
|
|
|
2008-10-15 15:03:54 +00:00
|
|
|
|
2008-10-14 19:51:24 +00:00
|
|
|
/*
|
2008-10-15 15:03:54 +00:00
|
|
|
* Error message parsing functions
|
|
|
|
*
|
|
|
|
* Produces nicely formatted messages for parser/unparser errors with optional HINT
|
2008-10-14 19:51:24 +00:00
|
|
|
*/
|
2008-10-15 15:03:54 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
pg_parser_errhint(LWGEOM_PARSER_RESULT *lwg_parser_result)
|
|
|
|
{
|
|
|
|
char hintbuffer[128];
|
|
|
|
char *hintstart;
|
|
|
|
char *hintfinish;
|
|
|
|
|
|
|
|
/* Generate the HINT string as the last 40 chars up until the error location */
|
|
|
|
hintbuffer[0] = '\0';
|
|
|
|
hintfinish = (char *)lwg_parser_result->wkinput + lwg_parser_result->errlocation;
|
|
|
|
|
|
|
|
if (lwg_parser_result->errlocation <= 40)
|
|
|
|
hintstart = (char *)lwg_parser_result->wkinput;
|
|
|
|
else
|
|
|
|
hintstart = hintfinish - 40;
|
|
|
|
|
|
|
|
/* If we are not at the start of the buffer, prefix with "..." */
|
|
|
|
if (hintstart != lwg_parser_result->wkinput)
|
2008-10-15 21:44:19 +00:00
|
|
|
strncpy(hintbuffer, "...", 4);
|
2008-10-15 15:03:54 +00:00
|
|
|
|
|
|
|
/* Append to the existing string */
|
|
|
|
strncat(hintbuffer, hintstart, hintfinish-hintstart);
|
2008-10-16 08:33:25 +00:00
|
|
|
|
|
|
|
/* Only display the parser position if the location is > 0; this provides a nicer output when the first token
|
|
|
|
within the input stream cannot be matched */
|
|
|
|
if (lwg_parser_result->errlocation > 0)
|
|
|
|
{
|
|
|
|
ereport(ERROR,
|
|
|
|
(errmsg("%s", lwg_parser_result->message),
|
|
|
|
errhint("\"%s\" <-- parse error at position %d within geometry", hintbuffer, lwg_parser_result->errlocation))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ereport(ERROR,
|
|
|
|
(errmsg("%s", lwg_parser_result->message),
|
|
|
|
errhint("You must specify a valid OGC WKT geometry type such as POINT, LINESTRING or POLYGON"))
|
|
|
|
);
|
|
|
|
}
|
2008-10-15 15:03:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pg_unparser_errhint(LWGEOM_UNPARSER_RESULT *lwg_unparser_result)
|
|
|
|
{
|
|
|
|
/* For the unparser simply output the error message without any associated HINT */
|
|
|
|
elog(ERROR, "%s", lwg_unparser_result->message);
|
|
|
|
}
|
2008-10-14 19:51:24 +00:00
|
|
|
|
|
|
|
|
2004-09-29 10:50:30 +00:00
|
|
|
void *
|
|
|
|
pg_alloc(size_t size)
|
2004-08-25 07:28:28 +00:00
|
|
|
{
|
|
|
|
void * result;
|
2008-05-31 09:56:44 +00:00
|
|
|
|
|
|
|
POSTGIS_DEBUGF(5, " pg_alloc(%d) called", (int)size);
|
|
|
|
|
2004-08-25 07:28:28 +00:00
|
|
|
result = palloc(size);
|
2008-05-31 09:56:44 +00:00
|
|
|
|
|
|
|
POSTGIS_DEBUGF(5, " pg_alloc(%d) returning %p", (int)size, result);
|
|
|
|
|
2004-10-04 13:53:42 +00:00
|
|
|
if ( ! result )
|
|
|
|
{
|
2008-05-31 09:56:44 +00:00
|
|
|
ereport(ERROR, (errmsg_internal("Out of virtual memory")));
|
2004-10-04 13:53:42 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2004-08-25 07:28:28 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2004-09-29 10:50:30 +00:00
|
|
|
void *
|
|
|
|
pg_realloc(void *mem, size_t size)
|
|
|
|
{
|
|
|
|
void * result;
|
2008-05-31 09:56:44 +00:00
|
|
|
|
|
|
|
POSTGIS_DEBUGF(5, " pg_realloc(%p, %d) called", mem, (int)size);
|
|
|
|
|
2004-09-29 10:50:30 +00:00
|
|
|
result = repalloc(mem, size);
|
2008-05-31 09:56:44 +00:00
|
|
|
|
|
|
|
POSTGIS_DEBUGF(5, " pg_realloc(%p, %d) returning %p", mem, (int)size, result);
|
|
|
|
|
2004-09-29 10:50:30 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pg_free(void *ptr)
|
2004-08-25 07:28:28 +00:00
|
|
|
{
|
|
|
|
pfree(ptr);
|
|
|
|
}
|
2004-09-29 10:50:30 +00:00
|
|
|
|
|
|
|
void
|
2008-09-23 19:44:57 +00:00
|
|
|
pg_error(const char *fmt, va_list ap)
|
2004-09-29 10:50:30 +00:00
|
|
|
{
|
2005-06-17 14:51:53 +00:00
|
|
|
#define ERRMSG_MAXLEN 256
|
|
|
|
|
|
|
|
char errmsg[ERRMSG_MAXLEN+1];
|
2004-09-29 10:50:30 +00:00
|
|
|
|
2005-06-17 14:51:53 +00:00
|
|
|
vsnprintf (errmsg, ERRMSG_MAXLEN, fmt, ap);
|
2004-09-29 10:50:30 +00:00
|
|
|
|
2005-06-17 14:51:53 +00:00
|
|
|
errmsg[ERRMSG_MAXLEN]='\0';
|
2008-05-31 09:56:44 +00:00
|
|
|
ereport(ERROR, (errmsg_internal("%s", errmsg)));
|
2004-09-29 10:50:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-09-23 19:44:57 +00:00
|
|
|
pg_notice(const char *fmt, va_list ap)
|
2004-09-29 10:50:30 +00:00
|
|
|
{
|
|
|
|
char *msg;
|
|
|
|
|
|
|
|
/*
|
2004-11-02 16:48:54 +00:00
|
|
|
* This is a GNU extension.
|
|
|
|
* Dunno how to handle errors here.
|
|
|
|
*/
|
2008-09-23 19:44:57 +00:00
|
|
|
if (!lw_vasprintf (&msg, fmt, ap))
|
2004-09-29 10:50:30 +00:00
|
|
|
{
|
|
|
|
va_end (ap);
|
|
|
|
return;
|
|
|
|
}
|
2008-05-31 09:56:44 +00:00
|
|
|
ereport(NOTICE, (errmsg_internal("%s", msg)));
|
2004-09-29 10:50:30 +00:00
|
|
|
free(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-06-29 19:11:48 +00:00
|
|
|
lwgeom_init_allocators(void)
|
2004-09-29 10:50:30 +00:00
|
|
|
{
|
2008-06-29 19:11:48 +00:00
|
|
|
/* liblwgeom callback - install PostgreSQL handlers */
|
2004-10-07 10:03:23 +00:00
|
|
|
lwalloc_var = pg_alloc;
|
|
|
|
lwrealloc_var = pg_realloc;
|
|
|
|
lwfree_var = pg_free;
|
2008-09-23 19:44:57 +00:00
|
|
|
lwerror_var = pg_error;
|
|
|
|
lwnotice_var = pg_notice;
|
2004-09-29 10:50:30 +00:00
|
|
|
}
|
2004-10-07 10:03:23 +00:00
|
|
|
|
2004-10-28 09:00:11 +00:00
|
|
|
PG_LWGEOM *
|
|
|
|
pglwgeom_serialize(LWGEOM *in)
|
|
|
|
{
|
|
|
|
size_t size;
|
|
|
|
PG_LWGEOM *result;
|
|
|
|
|
2008-05-14 17:10:19 +00:00
|
|
|
#if POSTGIS_AUTOCACHE_BBOX
|
2005-01-05 09:47:58 +00:00
|
|
|
if ( ! in->bbox && is_worth_caching_lwgeom_bbox(in) )
|
|
|
|
{
|
|
|
|
lwgeom_addBBOX(in);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-12-31 11:26:15 +00:00
|
|
|
size = lwgeom_serialize_size(in) + VARHDRSZ;
|
2006-12-01 22:16:44 +00:00
|
|
|
|
2008-05-31 09:56:44 +00:00
|
|
|
POSTGIS_DEBUGF(3, "lwgeom_serialize_size returned %d", (int)size-VARHDRSZ);
|
2006-12-01 22:16:44 +00:00
|
|
|
|
2004-12-31 11:26:15 +00:00
|
|
|
result = palloc(size);
|
2008-05-31 09:56:44 +00:00
|
|
|
SET_VARSIZE(result, size);
|
2004-10-28 09:00:11 +00:00
|
|
|
lwgeom_serialize_buf(in, SERIALIZED_FORM(result), &size);
|
2005-12-30 17:40:37 +00:00
|
|
|
|
2008-05-31 09:56:44 +00:00
|
|
|
POSTGIS_DEBUGF(3, "pglwgeom_serialize: serialized size: %d, computed size: %d", (int)size, VARSIZE(result)-VARHDRSZ);
|
2006-12-01 22:16:44 +00:00
|
|
|
|
2005-12-30 17:40:37 +00:00
|
|
|
#if PARANOIA_LEVEL > 0
|
2007-05-31 13:18:04 +00:00
|
|
|
if ( size != VARSIZE(result)-VARHDRSZ )
|
2004-10-28 09:00:11 +00:00
|
|
|
{
|
2008-05-31 09:56:44 +00:00
|
|
|
lwerror("pglwgeom_serialize: serialized size:%d, computed size:%d", (int)size, VARSIZE(result)-VARHDRSZ);
|
2004-10-28 09:00:11 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-12-30 17:40:37 +00:00
|
|
|
#endif
|
2004-10-28 09:00:11 +00:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2005-01-07 14:20:14 +00:00
|
|
|
|
2005-10-25 11:16:09 +00:00
|
|
|
LWGEOM *
|
|
|
|
pglwgeom_deserialize(PG_LWGEOM *in)
|
|
|
|
{
|
|
|
|
return lwgeom_deserialize(SERIALIZED_FORM(in));
|
|
|
|
}
|
|
|
|
|
2005-01-07 14:20:14 +00:00
|
|
|
Oid
|
2005-03-18 12:36:27 +00:00
|
|
|
getGeometryOID(void)
|
2005-01-07 14:20:14 +00:00
|
|
|
{
|
|
|
|
static Oid OID = InvalidOid;
|
|
|
|
int SPIcode;
|
|
|
|
bool isnull;
|
|
|
|
char *query = "select OID from pg_type where typname = 'geometry'";
|
|
|
|
|
|
|
|
if ( OID != InvalidOid ) return OID;
|
|
|
|
|
|
|
|
SPIcode = SPI_connect();
|
|
|
|
if (SPIcode != SPI_OK_CONNECT) {
|
|
|
|
lwerror("getGeometryOID(): couldn't connection to SPI");
|
|
|
|
}
|
|
|
|
|
|
|
|
SPIcode = SPI_exec(query, 0);
|
|
|
|
if (SPIcode != SPI_OK_SELECT ) {
|
|
|
|
lwerror("getGeometryOID(): error querying geometry oid");
|
|
|
|
}
|
|
|
|
if (SPI_processed != 1) {
|
|
|
|
lwerror("getGeometryOID(): error querying geometry oid");
|
|
|
|
}
|
|
|
|
|
|
|
|
OID = (Oid)SPI_getbinval(SPI_tuptable->vals[0],
|
|
|
|
SPI_tuptable->tupdesc, 1, &isnull);
|
|
|
|
|
|
|
|
if (isnull)
|
|
|
|
lwerror("getGeometryOID(): couldn't find geometry oid");
|
|
|
|
|
|
|
|
return OID;
|
|
|
|
}
|
2005-03-04 09:03:32 +00:00
|
|
|
|
|
|
|
PG_LWGEOM *
|
|
|
|
PG_LWGEOM_construct(uchar *ser, int SRID, int wantbbox)
|
|
|
|
{
|
|
|
|
int size;
|
|
|
|
uchar *iptr, *optr, *eptr;
|
|
|
|
int wantsrid = 0;
|
|
|
|
BOX2DFLOAT4 box;
|
|
|
|
PG_LWGEOM *result;
|
|
|
|
|
|
|
|
/* COMPUTE_BBOX FOR_COMPLEX_GEOMS */
|
|
|
|
if ( is_worth_caching_serialized_bbox(ser) )
|
|
|
|
{
|
2005-12-30 17:40:37 +00:00
|
|
|
/* if ( ! wantbbox ) elog(NOTICE, "PG_LWGEOM_construct forced wantbbox=1 due to rule FOR_COMPLEX_GEOMS"); */
|
2005-03-04 09:03:32 +00:00
|
|
|
wantbbox=1;
|
|
|
|
}
|
|
|
|
|
|
|
|
size = lwgeom_size(ser);
|
2005-12-30 17:40:37 +00:00
|
|
|
eptr = ser+size; /* end of subgeom */
|
2005-03-04 09:03:32 +00:00
|
|
|
|
2005-12-30 17:40:37 +00:00
|
|
|
iptr = ser+1; /* skip type */
|
2005-03-04 09:03:32 +00:00
|
|
|
if ( lwgeom_hasSRID(ser[0]) )
|
|
|
|
{
|
2005-12-30 17:40:37 +00:00
|
|
|
iptr += 4; /* skip SRID */
|
2005-03-04 09:03:32 +00:00
|
|
|
size -= 4;
|
|
|
|
}
|
|
|
|
if ( lwgeom_hasBBOX(ser[0]) )
|
|
|
|
{
|
2005-12-30 17:40:37 +00:00
|
|
|
iptr += sizeof(BOX2DFLOAT4); /* skip BBOX */
|
2005-03-04 09:03:32 +00:00
|
|
|
size -= sizeof(BOX2DFLOAT4);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( SRID != -1 )
|
|
|
|
{
|
|
|
|
wantsrid = 1;
|
|
|
|
size += 4;
|
|
|
|
}
|
|
|
|
if ( wantbbox )
|
|
|
|
{
|
|
|
|
size += sizeof(BOX2DFLOAT4);
|
|
|
|
getbox2d_p(ser, &box);
|
|
|
|
}
|
|
|
|
|
2005-12-30 17:40:37 +00:00
|
|
|
size+=4; /* size header */
|
2005-03-04 09:03:32 +00:00
|
|
|
|
|
|
|
result = lwalloc(size);
|
2008-05-31 09:56:44 +00:00
|
|
|
SET_VARSIZE(result, size);
|
2005-03-04 09:03:32 +00:00
|
|
|
|
|
|
|
result->type = lwgeom_makeType_full(
|
|
|
|
TYPE_HASZ(ser[0]), TYPE_HASM(ser[0]),
|
|
|
|
wantsrid, lwgeom_getType(ser[0]), wantbbox);
|
|
|
|
optr = result->data;
|
|
|
|
if ( wantbbox )
|
|
|
|
{
|
|
|
|
memcpy(optr, &box, sizeof(BOX2DFLOAT4));
|
|
|
|
optr += sizeof(BOX2DFLOAT4);
|
|
|
|
}
|
|
|
|
if ( wantsrid )
|
|
|
|
{
|
|
|
|
memcpy(optr, &SRID, 4);
|
|
|
|
optr += 4;
|
|
|
|
}
|
|
|
|
memcpy(optr, iptr, eptr-iptr);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2005-12-30 17:40:37 +00:00
|
|
|
/*
|
|
|
|
* Make a PG_LWGEOM object from a WKB binary representation.
|
|
|
|
*/
|
|
|
|
PG_LWGEOM *
|
2008-09-25 21:50:19 +00:00
|
|
|
pglwgeom_from_ewkb(uchar *ewkb, int flags, size_t ewkblen)
|
2005-12-30 17:40:37 +00:00
|
|
|
{
|
|
|
|
PG_LWGEOM *ret;
|
2008-09-28 15:32:46 +00:00
|
|
|
LWGEOM_PARSER_RESULT lwg_parser_result;
|
2005-12-30 17:40:37 +00:00
|
|
|
char *hexewkb;
|
|
|
|
size_t hexewkblen = ewkblen*2;
|
2008-09-28 15:32:46 +00:00
|
|
|
int i, result;
|
2005-12-30 17:40:37 +00:00
|
|
|
|
|
|
|
hexewkb = lwalloc(hexewkblen+1);
|
|
|
|
for (i=0; i<ewkblen; i++)
|
|
|
|
{
|
|
|
|
deparse_hex(ewkb[i], &hexewkb[i*2]);
|
|
|
|
}
|
|
|
|
hexewkb[hexewkblen] = '\0';
|
|
|
|
|
2008-09-28 15:32:46 +00:00
|
|
|
result = serialized_lwgeom_from_ewkt(&lwg_parser_result, hexewkb, flags);
|
2008-10-14 19:51:24 +00:00
|
|
|
if (result)
|
|
|
|
PG_PARSER_ERROR(lwg_parser_result);
|
2008-09-28 15:32:46 +00:00
|
|
|
|
2008-09-28 16:18:12 +00:00
|
|
|
ret = (PG_LWGEOM *)palloc(lwg_parser_result.size + VARHDRSZ);
|
|
|
|
SET_VARSIZE(ret, lwg_parser_result.size + VARHDRSZ);
|
|
|
|
memcpy(VARDATA(ret), lwg_parser_result.serialized_lwgeom, lwg_parser_result.size);
|
2005-12-30 17:40:37 +00:00
|
|
|
|
|
|
|
lwfree(hexewkb);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return the EWKB (binary) representation for a PG_LWGEOM.
|
|
|
|
*/
|
|
|
|
char *
|
2008-09-25 21:50:19 +00:00
|
|
|
pglwgeom_to_ewkb(PG_LWGEOM *geom, int flags, char byteorder, size_t *outsize)
|
2005-12-30 17:40:37 +00:00
|
|
|
{
|
2008-09-28 19:48:17 +00:00
|
|
|
LWGEOM_UNPARSER_RESULT lwg_unparser_result;
|
|
|
|
int result;
|
2008-10-14 19:51:24 +00:00
|
|
|
char *wkoutput;
|
2005-12-30 17:40:37 +00:00
|
|
|
uchar *srl = &(geom->type);
|
2008-09-28 19:48:17 +00:00
|
|
|
|
|
|
|
result = serialized_lwgeom_to_ewkb(&lwg_unparser_result, srl, flags, byteorder);
|
2008-10-14 19:51:24 +00:00
|
|
|
if (result)
|
|
|
|
PG_UNPARSER_ERROR(lwg_unparser_result);
|
2008-09-28 19:48:17 +00:00
|
|
|
|
|
|
|
*outsize = lwg_unparser_result.size;
|
2008-10-14 19:51:24 +00:00
|
|
|
|
|
|
|
/* Make a copy of the wkoutput so it can be used outside of the function */
|
|
|
|
wkoutput = palloc(lwg_unparser_result.size);
|
|
|
|
memcpy(wkoutput, lwg_unparser_result.wkoutput, lwg_unparser_result.size);
|
|
|
|
|
|
|
|
return wkoutput;
|
2005-12-30 17:40:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the SRID of a PG_LWGEOM
|
|
|
|
* Returns a newly allocated PG_LWGEOM object.
|
|
|
|
* Allocation will be done using the lwalloc.
|
|
|
|
*/
|
|
|
|
PG_LWGEOM *
|
|
|
|
pglwgeom_setSRID(PG_LWGEOM *lwgeom, int32 newSRID)
|
|
|
|
{
|
|
|
|
uchar type = lwgeom->type;
|
|
|
|
int bbox_offset=0; /* 0=no bbox, otherwise sizeof(BOX2DFLOAT4) */
|
|
|
|
int len,len_new,len_left;
|
|
|
|
PG_LWGEOM *result;
|
|
|
|
uchar *loc_new, *loc_old;
|
|
|
|
|
|
|
|
if (lwgeom_hasBBOX(type))
|
|
|
|
bbox_offset = sizeof(BOX2DFLOAT4);
|
|
|
|
|
|
|
|
len = lwgeom->size;
|
|
|
|
|
|
|
|
if (lwgeom_hasSRID(type))
|
|
|
|
{
|
|
|
|
if ( newSRID != -1 ) {
|
|
|
|
/* we create a new one and copy the SRID in */
|
|
|
|
result = lwalloc(len);
|
|
|
|
memcpy(result, lwgeom, len);
|
|
|
|
memcpy(result->data+bbox_offset, &newSRID,4);
|
|
|
|
} else {
|
|
|
|
/* we create a new one dropping the SRID */
|
|
|
|
result = lwalloc(len-4);
|
|
|
|
result->size = len-4;
|
|
|
|
result->type = lwgeom_makeType_full(
|
|
|
|
TYPE_HASZ(type), TYPE_HASM(type),
|
|
|
|
0, lwgeom_getType(type),
|
|
|
|
lwgeom_hasBBOX(type));
|
|
|
|
loc_new = result->data;
|
|
|
|
loc_old = lwgeom->data;
|
|
|
|
len_left = len-4-1;
|
|
|
|
|
|
|
|
/* handle bbox (if there) */
|
|
|
|
if (lwgeom_hasBBOX(type))
|
|
|
|
{
|
|
|
|
memcpy(loc_new, loc_old, sizeof(BOX2DFLOAT4));
|
|
|
|
loc_new += sizeof(BOX2DFLOAT4);
|
|
|
|
loc_old += sizeof(BOX2DFLOAT4);
|
|
|
|
len_left -= sizeof(BOX2DFLOAT4);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* skip SRID, copy the remaining */
|
|
|
|
loc_old += 4;
|
|
|
|
len_left -= 4;
|
|
|
|
memcpy(loc_new, loc_old, len_left);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* just copy input, already w/out a SRID */
|
|
|
|
if ( newSRID == -1 ) {
|
|
|
|
result = lwalloc(len);
|
|
|
|
memcpy(result, lwgeom, len);
|
|
|
|
}
|
|
|
|
/* need to add one */
|
|
|
|
else {
|
|
|
|
len_new = len + 4; /* +4 for SRID */
|
|
|
|
result = lwalloc(len_new);
|
|
|
|
memcpy(result, &len_new, 4); /* size copy in */
|
|
|
|
result->type = lwgeom_makeType_full(
|
|
|
|
TYPE_HASZ(type), TYPE_HASM(type),
|
|
|
|
1, lwgeom_getType(type),lwgeom_hasBBOX(type));
|
|
|
|
|
|
|
|
loc_new = result->data;
|
|
|
|
loc_old = lwgeom->data;
|
|
|
|
|
|
|
|
len_left = len -4-1; /* old length - size - type */
|
|
|
|
|
|
|
|
/* handle bbox (if there) */
|
|
|
|
|
|
|
|
if (lwgeom_hasBBOX(type))
|
|
|
|
{
|
|
|
|
memcpy(loc_new, loc_old, sizeof(BOX2DFLOAT4)) ; /* copy in bbox */
|
|
|
|
loc_new += sizeof(BOX2DFLOAT4);
|
|
|
|
loc_old += sizeof(BOX2DFLOAT4);
|
|
|
|
len_left -= sizeof(BOX2DFLOAT4);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* put in SRID */
|
|
|
|
|
|
|
|
memcpy(loc_new, &newSRID,4);
|
|
|
|
loc_new +=4;
|
|
|
|
memcpy(loc_new, loc_old, len_left);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* get the SRID from the LWGEOM
|
|
|
|
* none present => -1
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
pglwgeom_getSRID(PG_LWGEOM *lwgeom)
|
|
|
|
{
|
|
|
|
uchar type = lwgeom->type;
|
|
|
|
uchar *loc = lwgeom->data;
|
|
|
|
|
|
|
|
if ( ! lwgeom_hasSRID(type)) return -1;
|
|
|
|
|
|
|
|
if (lwgeom_hasBBOX(type))
|
|
|
|
{
|
|
|
|
loc += sizeof(BOX2DFLOAT4);
|
|
|
|
}
|
|
|
|
|
2007-11-27 22:39:06 +00:00
|
|
|
return lw_get_int32(loc);
|
2005-12-30 17:40:37 +00:00
|
|
|
}
|
|
|
|
|