2
* Written by Ralph Mason ralph.mason<at>telogis.com
4
* Copyright Telogis 2004
7
* $Id: lwgunparse.c 4233 2009-07-01 01:12:40Z mleslie $
14
/* Solaris9 does not provide stdint.h */
15
/* #include <stdint.h> */
18
#include "liblwgeom.h"
22
/*-- Typedefs ---------------------------------------------- */
24
typedef uint32_t int4;
25
typedef uchar* (*outfunc)(uchar*,int);
26
typedef uchar* (*outwkbfunc)(uchar*);
28
/*-- Prototypes -------------------------------------------- */
30
void ensure(int chars);
32
void write_str(const char* str);
33
void write_double(double val);
34
void write_int(int i);
35
int4 read_int(uchar** geom);
36
double read_double(uchar** geom);
37
uchar* output_point(uchar* geom,int supress);
38
uchar* output_single(uchar* geom,int supress);
39
uchar* output_collection(uchar* geom,outfunc func,int supress);
40
uchar* output_line_collection(uchar* geom,outfunc func,int supress);
41
uchar* output_polygon_collection(uchar* geom,int suppress);
42
uchar* output_polygon_ring_collection(uchar* geom,outfunc func,int supress);
43
uchar* output_circstring_collection(uchar* geom,outfunc func,int supress);
44
uchar* output_curvepoly(uchar* geom, int supress);
45
uchar* output_multipoint(uchar* geom,int suppress);
46
uchar* output_compound(uchar* geom, int suppress);
47
uchar* output_multisurface(uchar* geom, int suppress);
49
void write_wkb_hex_bytes(uchar* ptr, unsigned int cnt, size_t size);
50
void write_wkb_bin_bytes(uchar* ptr, unsigned int cnt, size_t size);
51
void write_wkb_bin_flip_bytes(uchar* ptr, unsigned int cnt, size_t size);
52
void write_wkb_hex_flip_bytes(uchar* ptr, unsigned int cnt, size_t size);
54
void write_wkb_int(int i);
55
uchar* output_wkb_collection(uchar* geom,outwkbfunc func);
56
uchar* output_wkb_polygon_collection(uchar* geom);
57
uchar* output_wkb_polygon_ring_collection(uchar* geom,outwkbfunc func);
58
uchar* output_wkb_line_collection(uchar* geom,outwkbfunc func);
59
uchar* output_wkb_circstring_collection(uchar* geom,outwkbfunc func);
60
uchar* output_wkb_point(uchar* geom);
61
uchar* output_wkb(uchar* geom);
63
/*-- Globals ----------------------------------------------- */
65
static int unparser_ferror_occured;
67
static allocator local_malloc;
68
static freeor local_free;
69
static char* out_start;
73
static uchar endianbyte;
74
void (*write_wkb_bytes)(uchar* ptr,unsigned int cnt,size_t size);
77
* Unparser current instance check flags - a bitmap of flags that determine which checks are enabled during the current unparse
78
* (see liblwgeom.h for the related PARSER_CHECK constants)
80
int current_unparser_check_flags;
83
* Unparser current instance result structure - the result structure being used for the current unparse
85
LWGEOM_UNPARSER_RESULT *current_lwg_unparser_result;
88
* Unparser error messages
90
* IMPORTANT: Make sure the order of these messages matches the UNPARSER_ERROR constants in liblwgeom.h!
91
* The 0th element should always be empty since it is unused (error constants start from -1)
94
const char *unparser_error_messages[] =
97
"geometry requires more points",
98
"geometry must have an odd number of points",
99
"geometry contains non-closed rings"
102
/* Macro to return the error message and the current position within WKT */
103
#define LWGEOM_WKT_UNPARSER_ERROR(errcode) \
105
if (!unparser_ferror_occured) { \
106
unparser_ferror_occured = -1 * errcode; \
107
current_lwg_unparser_result->message = unparser_error_messages[errcode]; \
108
current_lwg_unparser_result->errlocation = (out_pos - out_start); \
112
/* Macro to return the error message and the current position within WKB */
113
#define LWGEOM_WKB_UNPARSER_ERROR(errcode) \
115
if (!unparser_ferror_occured) { \
116
unparser_ferror_occured = -1 * errcode; \
117
current_lwg_unparser_result->message = unparser_error_messages[errcode]; \
118
current_lwg_unparser_result->errlocation = (out_pos - out_start); \
122
/*---------------------------------------------------------- */
130
* Ensure there is enough space for chars bytes.
131
* Reallocate memory is this is not the case.
137
int pos = out_pos - out_start;
139
if ( (pos + chars) >= len )
141
char* newp =(char*)local_malloc(len*2);
142
memcpy(newp,out_start,len);
143
local_free(out_start);
145
out_pos = newp + pos;
160
write_str(const char* str)
168
write_double(double val)
172
sprintf(out_pos,"%.8g",val);
174
sprintf(out_pos,"%.15g",val);
182
sprintf(out_pos,"%i",i);
187
read_int(uchar** geom)
191
if ( getMachineEndian() == NDR )
204
ret = **geom & ~0x80;
210
memcpy(&ret,*geom,4);
213
if ( getMachineEndian() == NDR )
223
double round(double);
225
double read_double(uchar** geom)
229
double ret = *((int4*)*geom);
237
memcpy(&ret, *geom, 8);
244
output_point(uchar* geom,int supress)
248
for ( i = 0 ; i < dims ; i++ )
250
write_double(read_double(&geom));
258
output_single(uchar* geom,int supress)
261
geom=output_point(geom,supress);
266
/* Output a standard collection */
268
output_collection(uchar* geom,outfunc func,int supress)
270
int cnt = read_int(&geom);
280
geom=func(geom,supress);
291
/* Output a set of LINESTRING points */
293
output_line_collection(uchar* geom,outfunc func,int supress)
295
int cnt = read_int(&geom);
307
geom=func(geom,supress);
316
/* Ensure that LINESTRING has a minimum of 2 points */
317
if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 2)
318
LWGEOM_WKT_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
323
/* Output an individual ring from a POLYGON */
325
output_polygon_ring_collection(uchar* geom,outfunc func,int supress)
334
first_point = lwalloc(dims * sizeof(double));
335
last_point = lwalloc(dims * sizeof(double));
337
cnt = read_int(&geom);
347
/* Store the first point of the ring (use a temp var since read_double alters
348
the pointer after use) */
351
while (dimcount < dims)
353
first_point[dimcount] = read_double(&temp);
359
geom=func(geom,supress);
367
/* Store the last point of the ring (note: we will have moved past it, so we
368
need to count backwards) */
369
temp = geom - sizeof(double) * dims;
371
while (dimcount < dims)
373
last_point[dimcount] = read_double(&temp);
377
/* Check if they are the same...
379
WARNING: due to various GEOS bugs related to producing rings with incorrect
380
3rd dimensions, the closure check here for outgoing geometries only checks on 2
381
dimensions. This is currently different to the parser! */
384
(first_point[0] != last_point[0] || first_point[1] != last_point[1] ) &&
385
(current_unparser_check_flags & PARSER_CHECK_CLOSURE))
387
LWGEOM_WKT_UNPARSER_ERROR(UNPARSER_ERROR_UNCLOSED);
391
/* Ensure that POLYGON has a minimum of 4 points */
392
if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 4)
394
LWGEOM_WKT_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
404
/* Ouput the points from a CIRCULARSTRING */
406
output_circstring_collection(uchar* geom,outfunc func,int supress)
408
int cnt = read_int(&geom);
420
geom=func(geom,supress);
429
/* Ensure that a CIRCULARSTRING has a minimum of 3 points */
430
if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 3)
432
LWGEOM_WKT_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
435
/* Ensure that a CIRCULARSTRING has an odd number of points */
436
if ((current_unparser_check_flags & PARSER_CHECK_ODD) && orig_cnt % 2 != 1)
438
LWGEOM_WKT_UNPARSER_ERROR(UNPARSER_ERROR_ODDPOINTS);
444
/* Output a POLYGON consisting of a number of rings */
446
output_polygon_collection(uchar* geom,int suppress)
448
return output_polygon_ring_collection(geom,output_point,suppress);
451
uchar *output_wkt(uchar* geom, int supress);
453
/* special case for multipoint to supress extra brackets */
454
uchar *output_multipoint(uchar* geom,int suppress)
456
unsigned char type = *geom & 0x0f;
458
if ( type == POINTTYPE )
459
return output_point(++geom,suppress);
460
else if ( type == POINTTYPEI )
463
geom=output_point(++geom,0);
468
return output_wkt(geom,suppress);
471
/* Special case for compound curves: suppress the LINESTRING prefix from a curve if it appears as
472
a component of a COMPOUNDCURVE, but not CIRCULARSTRING */
473
uchar *output_compound(uchar* geom, int suppress)
477
LWDEBUG(2, "output_compound called.");
480
switch (TYPE_GETTYPE(type))
483
geom = output_wkt(geom,2);
486
geom = output_wkt(geom,1);
493
* Supress linestring but not circularstring and correctly handle compoundcurve
495
uchar *output_curvepoly(uchar* geom, int supress)
500
LWDEBUG(2, "output_curvepoly.");
502
switch (TYPE_GETTYPE(type))
505
geom = output_collection(geom,output_point,0);
508
write_str("CIRCULARSTRING");
509
geom = output_circstring_collection(geom,output_point,1);
512
write_str("COMPOUNDCURVE");
513
geom = output_collection(geom,output_compound,1);
519
/* Special case for multisurfaces: suppress the POLYGON prefix from a surface if it appears as
520
a component of a MULTISURFACE, but not CURVEPOLYGON */
521
uchar *output_multisurface(uchar* geom, int suppress)
525
LWDEBUG(2, "output_multisurface called.");
528
switch (TYPE_GETTYPE(type))
531
geom = output_wkt(geom,2);
534
geom = output_wkt(geom,1);
541
* Suppress=0 -- write TYPE, M, coords
542
* Suppress=1 -- write TYPE, coords
543
* Suppress=2 -- write only coords
546
output_wkt(uchar* geom, int supress)
549
unsigned char type=*geom++;
551
dims = TYPE_NDIMS(type); /* ((type & 0x30) >> 4)+2; */
553
LWDEBUG(2, "output_wkt called.");
555
if ( ! supress && !TYPE_HASZ(type) && TYPE_HASM(type) ) writeM=1;
558
/* Skip the bounding box if there is one */
559
if ( TYPE_HASBBOX(type) )
564
if ( TYPE_HASSRID(type) )
567
write_int(read_int(&geom));
571
switch (TYPE_GETTYPE(type))
576
if (writeM) write_str("POINTM");
577
else write_str("POINT");
579
geom=output_single(geom,0);
584
if (writeM) write_str("LINESTRINGM");
585
else write_str("LINESTRING");
587
geom = output_line_collection(geom,output_point,0);
592
if (writeM) write_str("CIRCULARSTRINGM");
593
else write_str("CIRCULARSTRING");
595
geom = output_circstring_collection(geom,output_point,0);
600
if (writeM) write_str("POLYGONM");
601
else write_str("POLYGON");
603
geom = output_collection(geom,output_polygon_collection,0);
608
if (writeM) write_str("COMPOUNDCURVEM");
609
else write_str("COMPOUNDCURVE");
611
geom = output_collection(geom, output_compound,1);
616
if (writeM) write_str("CURVEPOLYGONM");
617
else write_str("CURVEPOLYGON");
619
geom = output_collection(geom, output_curvepoly,0);
624
if (writeM) write_str("MULTIPOINTM");
625
else write_str("MULTIPOINT");
627
geom = output_collection(geom,output_multipoint,2);
632
if (writeM) write_str("MULTILINESTRINGM");
633
else write_str("MULTILINESTRING");
635
geom = output_collection(geom,output_wkt,2);
640
if (writeM) write_str("MULTICURVEM");
641
else write_str("MULTICURVE");
643
geom = output_collection(geom,output_compound,2);
645
case MULTIPOLYGONTYPE:
648
if (writeM) write_str("MULTIPOLYGONM");
649
else write_str("MULTIPOLYGON");
651
geom = output_collection(geom,output_wkt,2);
653
case MULTISURFACETYPE:
656
if (writeM) write_str("MULTISURFACEM");
657
else write_str("MULTISURFACE");
659
geom = output_collection(geom,output_multisurface,2);
664
if (writeM) write_str("GEOMETRYCOLLECTIONM");
665
else write_str("GEOMETRYCOLLECTION");
667
geom = output_collection(geom,output_wkt,1);
673
if (writeM) write_str("POINTM");
674
else write_str("POINT");
677
geom=output_single(geom,0);
683
if (writeM) write_str("LINESTRINGM");
684
else write_str("LINESTRING");
687
geom = output_collection(geom,output_point,0);
693
if (writeM) write_str("POLYGONM");
694
else write_str("POLYGON");
697
geom = output_collection(geom,output_polygon_collection,0);
705
unparse_WKT(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar* serialized, allocator alloc, freeor free, int flags)
708
LWDEBUGF(2, "unparse_WKT called with parser flags %d.", flags);
710
if (serialized==NULL)
713
/* Setup the inital parser flags and empty the return struct */
714
current_lwg_unparser_result = lwg_unparser_result;
715
current_unparser_check_flags = flags;
716
lwg_unparser_result->wkoutput = NULL;
717
lwg_unparser_result->size = 0;
718
lwg_unparser_result->serialized_lwgeom = serialized;
720
unparser_ferror_occured = 0;
724
out_start = out_pos = alloc(len);
727
output_wkt(serialized, 0);
729
/* Store the result in the struct */
730
lwg_unparser_result->wkoutput = out_start;
731
lwg_unparser_result->size = strlen(out_start);
733
return unparser_ferror_occured;
736
static char outchr[]=
740
/* Write HEX bytes flipping */
742
write_wkb_hex_flip_bytes(uchar* ptr, unsigned int cnt, size_t size)
744
unsigned int bc; /* byte count */
750
for (bc=size; bc; bc--)
752
*out_pos++ = outchr[ptr[bc-1]>>4];
753
*out_pos++ = outchr[ptr[bc-1]&0x0F];
759
/* Write HEX bytes w/out flipping */
761
write_wkb_hex_bytes(uchar* ptr, unsigned int cnt, size_t size)
763
unsigned int bc; /* byte count */
769
for (bc=0; bc<size; bc++)
771
*out_pos++ = outchr[ptr[bc]>>4];
772
*out_pos++ = outchr[ptr[bc]&0x0F];
778
/* Write BIN bytes flipping */
780
write_wkb_bin_flip_bytes(uchar* ptr, unsigned int cnt, size_t size)
782
unsigned int bc; /* byte count */
788
for (bc=size; bc; bc--)
789
*out_pos++ = ptr[bc-1];
795
/* Write BIN bytes w/out flipping */
797
write_wkb_bin_bytes(uchar* ptr, unsigned int cnt, size_t size)
799
unsigned int bc; /* byte count */
803
/* Could just use a memcpy here ... */
806
for (bc=0; bc<size; bc++)
807
*out_pos++ = ptr[bc];
813
output_wkb_point(uchar* geom)
817
write_wkb_bytes(geom,dims,4);
818
return geom + (4*dims);
822
write_wkb_bytes(geom,dims,8);
823
return geom + (8*dims);
830
write_wkb_bytes((uchar*)&i,1,4);
833
/* Output a standard collection */
835
output_wkb_collection(uchar* geom,outwkbfunc func)
837
int cnt = read_int(&geom);
839
LWDEBUGF(2, "output_wkb_collection: %d iterations loop", cnt);
842
while (cnt--) geom=func(geom);
846
/* Output a set of LINESTRING points */
848
output_wkb_line_collection(uchar* geom,outwkbfunc func)
850
int cnt = read_int(&geom);
853
LWDEBUGF(2, "output_wkb_line_collection: %d iterations loop", cnt);
856
while (cnt--) geom=func(geom);
858
/* Ensure that LINESTRING has a minimum of 2 points */
859
if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 2)
861
LWGEOM_WKB_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
867
/* Output an individual ring from a POLYGON */
869
output_wkb_polygon_ring_collection(uchar* geom,outwkbfunc func)
878
first_point = lwalloc(dims * sizeof(double));
879
last_point = lwalloc(dims * sizeof(double));
881
cnt = read_int(&geom);
884
LWDEBUGF(2, "output_wkb_polygon_ring_collection: %d iterations loop", cnt);
888
/* Store the first point of the ring (use a temp var since read_double alters
889
the pointer after use) */
892
while (dimcount < dims)
894
first_point[dimcount] = read_double(&temp);
898
while (cnt--) geom=func(geom);
900
/* Store the last point of the ring (note: we will have moved past it, so we
901
need to count backwards) */
902
temp = geom - sizeof(double) * dims;
904
while (dimcount < dims)
906
last_point[dimcount] = read_double(&temp);
910
/* Check if they are the same... */
911
if (((first_point[0] != last_point[0]) ||
912
(first_point[1] != last_point[1])) &&
913
(current_unparser_check_flags & PARSER_CHECK_CLOSURE))
915
LWGEOM_WKB_UNPARSER_ERROR(UNPARSER_ERROR_UNCLOSED);
918
/* Ensure that POLYGON has a minimum of 4 points */
919
if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 4)
921
LWGEOM_WKB_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
930
/* Output a POLYGON consisting of a number of rings */
932
output_wkb_polygon_collection(uchar* geom)
934
LWDEBUG(2, "output_wkb_polygon_collection");
936
return output_wkb_polygon_ring_collection(geom,output_wkb_point);
939
/* Ouput the points from a CIRCULARSTRING */
941
output_wkb_circstring_collection(uchar* geom,outwkbfunc func)
943
int cnt = read_int(&geom);
946
LWDEBUGF(2, "output_wkb_curve_collection: %d iterations loop", cnt);
949
while (cnt--) geom=func(geom);
951
/* Ensure that a CIRCULARSTRING has a minimum of 3 points */
952
if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 3)
954
LWGEOM_WKB_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
957
/* Ensure that a CIRCULARSTRING has an odd number of points */
958
if ((current_unparser_check_flags & PARSER_CHECK_ODD) && orig_cnt % 2 != 1)
960
LWGEOM_WKB_UNPARSER_ERROR(UNPARSER_ERROR_ODDPOINTS);
967
output_wkb(uchar* geom)
969
unsigned char type=*geom++;
972
dims = TYPE_NDIMS(type);
974
LWDEBUGF(2, "output_wkb: dims set to %d", dims);
976
/* Skip the bounding box */
977
if ( TYPE_HASBBOX(type) )
982
wkbtype = TYPE_GETTYPE(type);
984
if ( TYPE_HASZ(type) )
985
wkbtype |= WKBZOFFSET;
986
if ( TYPE_HASM(type) )
987
wkbtype |= WKBMOFFSET;
988
if ( TYPE_HASSRID(type) )
990
wkbtype |= WKBSRIDFLAG;
994
/* Write byteorder (as from WKB specs...) */
995
write_wkb_bytes(&endianbyte,1,1);
997
write_wkb_int(wkbtype);
999
if ( TYPE_HASSRID(type) )
1001
write_wkb_int(read_int(&geom));
1004
switch (TYPE_GETTYPE(type))
1007
geom=output_wkb_point(geom);
1010
geom=output_wkb_line_collection(geom,output_wkb_point);
1012
case CIRCSTRINGTYPE:
1013
geom=output_wkb_circstring_collection(geom,output_wkb_point);
1016
geom=output_wkb_collection(geom,output_wkb_polygon_collection);
1019
geom=output_wkb_collection(geom,output_wkb);
1022
geom=output_wkb_collection(geom,output_wkb);
1024
case MULTICURVETYPE:
1025
case MULTISURFACETYPE:
1026
case MULTIPOINTTYPE:
1028
case MULTIPOLYGONTYPE:
1029
case COLLECTIONTYPE:
1030
geom = output_wkb_collection(geom,output_wkb);
1034
These don't output standard wkb at the moment
1035
the output and integer version.
1037
however you could run it through the wkt parser
1038
for a lwg and then output that. There should
1039
also be a force_to_real_(lwgi)
1043
geom=output_wkb_point(geom);
1048
geom = output_wkb_collection(geom,output_wkb_point);
1053
geom = output_wkb_collection(geom,output_wkb_polygon_collection);
1061
unparse_WKB(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar* serialized, allocator alloc, freeor free, int flags, char endian, uchar hex)
1063
LWDEBUGF(2, "unparse_WKB(%p,...) called with parser flags %d", serialized, flags);
1068
/* Setup the inital parser flags and empty the return struct */
1069
current_lwg_unparser_result = lwg_unparser_result;
1070
current_unparser_check_flags = flags;
1071
lwg_unparser_result->wkoutput = NULL;
1072
lwg_unparser_result->size = 0;
1073
lwg_unparser_result->serialized_lwgeom = serialized;
1075
unparser_ferror_occured = 0;
1079
out_start = out_pos = alloc(len);
1082
if ( endian == (char)-1 )
1084
endianbyte = getMachineEndian();
1085
if ( hex ) write_wkb_bytes = write_wkb_hex_bytes;
1086
else write_wkb_bytes = write_wkb_bin_bytes;
1090
endianbyte = endian;
1091
if ( endianbyte != getMachineEndian() )
1093
if ( hex ) write_wkb_bytes = write_wkb_hex_flip_bytes;
1094
else write_wkb_bytes = write_wkb_bin_flip_bytes;
1098
if ( hex ) write_wkb_bytes = write_wkb_hex_bytes;
1099
else write_wkb_bytes = write_wkb_bin_bytes;
1103
output_wkb(serialized);
1111
/* Store the result in the struct */
1112
lwg_unparser_result->wkoutput = out_start;
1113
lwg_unparser_result->size = (out_pos-out_start);
1115
return unparser_ferror_occured;
1119
/******************************************************************
1121
* Revision 1.23 2006/02/06 11:12:22 strk
1122
* uint32_t typedef moved back from wktparse.h to lwgparse.c and wktunparse.c
1124
* Revision 1.22 2006/02/03 20:53:37 strk
1125
* Swapped stdint.h (unavailable on Solaris9) with inttypes.h
1127
* Revision 1.21 2006/02/03 09:52:14 strk
1128
* Changed int4 typedefs to use POSIX uint32_t
1130
* Revision 1.20 2006/01/09 15:12:02 strk
1133
* Revision 1.19 2005/03/10 18:19:16 strk
1134
* Made void args explicit to make newer compilers happy
1136
* Revision 1.18 2005/02/21 16:16:14 strk
1137
* Changed byte to uchar to avoid clashes with win32 headers.
1139
* Revision 1.17 2005/02/07 13:21:10 strk
1140
* Replaced DEBUG* macros with PGIS_DEBUG*, to avoid clashes with postgresql DEBUG
1142
* Revision 1.16 2005/01/18 09:32:03 strk
1143
* Changed unparse_WKB interface to take an output size pointer and an HEXFORM
1144
* specifier. Reworked code in wktunparse to use function pointers.
1146
* Revision 1.15 2004/12/21 15:19:01 strk
1147
* Canonical binary reverted back to EWKB, now supporting SRID inclusion.
1149
* Revision 1.14 2004/12/17 11:08:53 strk
1150
* Moved getMachineEndian from parser to liblwgeom.{h,c}.
1151
* Added XDR and NDR defines.
1152
* Fixed all usage of them.
1154
* Revision 1.13 2004/10/25 12:27:33 strk
1155
* Removed useless network type includes,
1156
* Added param.h include for BYTE_ORDER defines under win32.
1158
* Revision 1.12 2004/10/21 19:48:34 strk
1159
* Stricter syntax fixes. Reported by S�bastien NICAISE <snicaise@iciatechnologies.com>
1161
* Revision 1.11 2004/10/15 07:35:41 strk
1162
* Fixed a bug introduced by me (byteorder skipped for inner geoms in WKB)
1164
* Revision 1.10 2004/10/11 14:03:33 strk
1165
* Added endiannes specification to unparse_WKB, AsBinary, lwgeom_to_wkb.
1167
******************************************************************/