PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
cu_out_twkb.c
Go to the documentation of this file.
1/**********************************************************************
2 *
3 * PostGIS - Spatial Types for PostgreSQL
4 * http://postgis.net
5 * Copyright 2014 Nicklas Avén
6 *
7 * This is free software; you can redistribute and/or modify it under
8 * the terms of the GNU General Public Licence. See the COPYING file.
9 *
10 **********************************************************************/
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include "CUnit/Basic.h"
16
17#include "liblwgeom_internal.h"
18#include "cu_tester.h"
19
20
21/*
22** Global variable to hold hex TWKB strings
23*/
24static char *s;
25static char *w;
26
27/*
28** The suite initialization function.
29** Create any reused objects.
30*/
31static int init_twkb_out_suite(void)
32{
33 s = NULL;
34 w = NULL;
35 return 0;
36}
37
38/*
39** The suite cleanup function.
40** Frees any global objects.
41*/
42static int clean_twkb_out_suite(void)
43{
44 if (s) free(s);
45 if (w) free(w);
46 s = NULL;
47 w = NULL;
48 return 0;
49}
50
51
52/*
53** Creating an input TWKB from a wkt string
54*/
55static void cu_twkb(char *wkt, int8_t prec_xy, int8_t prec_z, int8_t prec_m, uint8_t variant)
56{
58 if ( ! g ) lwnotice("input wkt is invalid: %s", wkt);
59 lwvarlena_t *twkb = lwgeom_to_twkb(g, variant, prec_xy, prec_z, prec_m);
60 lwgeom_free(g);
61 if ( s ) free(s);
62 s = hexbytes_from_bytes((uint8_t *)twkb->data, LWSIZE_GET(twkb->size) - LWVARHDRSZ);
63 free(twkb);
64}
65
66
67/*
68** Creating an input TWKB from a wkt string
69*/
70static void cu_twkb_idlist(char *wkt, int64_t *idlist, int8_t prec_xy, int8_t prec_z, int8_t prec_m, uint8_t variant)
71{
73 LWGEOM *g_b;
74 if ( ! g ) lwnotice("input wkt is invalid: %s", wkt);
75 lwvarlena_t *twkb = lwgeom_to_twkb_with_idlist(g, idlist, variant, prec_xy, prec_z, prec_m);
76 lwgeom_free(g);
77 if ( s ) free(s);
78 if ( w ) free(w);
79 s = hexbytes_from_bytes((uint8_t *)twkb->data, LWSIZE_GET(twkb->size) - LWVARHDRSZ);
80 g_b = lwgeom_from_twkb((uint8_t *)twkb->data, LWSIZE_GET(twkb->size) - LWVARHDRSZ, LW_PARSER_CHECK_NONE);
81 w = lwgeom_to_ewkt(g_b);
82 lwgeom_free(g_b);
83 free(twkb);
84}
85
86
87
88static void test_twkb_out_point(void)
89{
90
91 cu_twkb("POINT EMPTY", 0, 0, 0, 0);
92 ASSERT_STRING_EQUAL(s,"0110");
93
94 cu_twkb("POINT(0 0)", 0, 0, 0, 0);
95 ASSERT_STRING_EQUAL(s,"01000000");
96
97 cu_twkb("POINT(0 0 0 0)", 0, 0, 0, 0);
98 ASSERT_STRING_EQUAL(s,"01080300000000");
99
100 /* Point with bounding box */
101 cu_twkb("POINT(0 0)", 0, 0, 0, TWKB_BBOX);
102 ASSERT_STRING_EQUAL(s,"0101000000000000");
103 // printf("TWKB: %s\n",s);
104
105 /* Adding a size parameters to X/Y */
106 cu_twkb("POINT(0 0)", 0, 0, 0, TWKB_SIZE);
107 ASSERT_STRING_EQUAL(s,"0102020000");
108
109 /* Adding a size parameters to X/Y/M */
110 cu_twkb("POINTM(0 0 0)", 0, 0, 0, TWKB_SIZE);
111 ASSERT_STRING_EQUAL(s,"010A0203000000");
112
113 /* Adding a size parameters to X/Y/Z/M */
114 cu_twkb("POINT(0 0 0 0)", 0, 0, 0, TWKB_SIZE);
115 ASSERT_STRING_EQUAL(s,"010A030400000000");
116
117 /* Since the third dimension is Z it shall get a precision of 1 decimal (third argument) */
118 cu_twkb("POINTZ(1 1 1)", 0,1,2, 0);
119 ASSERT_STRING_EQUAL(s,"010845020214");
120
121 /* Since the third dimension is M it shall get a precision of 2 decimals (fourth argument) */
122 cu_twkb("POINTM(1 1 1)", 0,1,2, 0);
123 // printf("\n%s\n", s);
124 ASSERT_STRING_EQUAL(s,"0108460202C801");
125}
126
128{
129
130 cu_twkb("LINESTRING(0 0,1 1)", 0, 0, 0, 0);
131 ASSERT_STRING_EQUAL(s,"02000200000202");
132 // printf("TWKB: %s\n",s);
133
134 cu_twkb("LINESTRING(0 0 1,1 1 2,2 2 3)", 0, 0, 0, 0);
135 ASSERT_STRING_EQUAL(s,"02080103000002020202020202");
136 // printf("TWKB: %s\n",s);
137
138 /* Line with bounding box */
139 cu_twkb("LINESTRING(0 0,1 1,2 2)", 0, 0, 0, TWKB_BBOX);
140 ASSERT_STRING_EQUAL(s,"02010004000403000002020202");
141 // printf("TWKB: %s\n",s);
142
143 cu_twkb("LINESTRING EMPTY", 0, 0, 0, 0);
144 ASSERT_STRING_EQUAL(s,"0210");
145 // printf("TWKB: %s\n",s);
146}
147
148static void test_twkb_out_polygon(void)
149{
150 cu_twkb("SRID=4;POLYGON((0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0))", 0, 0, 0, 0);
151 ASSERT_STRING_EQUAL(s,"0308010105000000000200020000000100010000");
152 // printf("TWKB: %s\n",s);
153
154 cu_twkb("SRID=14;POLYGON((0 0 0 1, 0 1 0 2,1 1 0 3,1 0 0 4, 0 0 0 5))", 0, 0, 0, 0);
155 ASSERT_STRING_EQUAL(s,"03080301050000000200020002020000020001000201000002");
156 // printf("TWKB: %s\n",s);
157
158 cu_twkb("POLYGON EMPTY", 0, 0, 0, 0);
159 ASSERT_STRING_EQUAL(s,"0310");
160 // printf("TWKB: %s\n",s);
161}
162
164{
165 cu_twkb("MULTIPOINT(0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0)", 0, 0, 0, 0);
166 ASSERT_STRING_EQUAL(s,"04080105000000000200020000000100010000");
167
168 cu_twkb("MULTIPOINT(0 0 0, 0.26794919243112270647255365849413 1 3)",7 ,7 , 0, 0);
169 //printf("WKB: %s",s);
170 ASSERT_STRING_EQUAL(s,"E4081D02000000888BC70280DAC409808ECE1C");
171// printf("TWKB: %s\n",s);
172}
173
175
177{
178 cu_twkb("MULTIPOLYGON(((0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0)),((-1 -1 0,-1 2 0,2 2 0,2 -1 0,-1 -1 0),(0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0)))", 0, 0, 0, 0);
179 ASSERT_STRING_EQUAL(s,"060801020105000000000200020000000100010000020501010000060006000000050005000005020200000200020000000100010000");
180}
181
183{
184 cu_twkb("GEOMETRYCOLLECTION(LINESTRING(1 1, 2 2), LINESTRING(3 3, 4 4), LINESTRING(5 5, 6 6))", 0, 0, 0, 0);
185 // printf("TWKB: %s\n",s);
186 ASSERT_STRING_EQUAL(s,"07000302000202020202020002060602020200020A0A0202");
187
188 cu_twkb("GEOMETRYCOLLECTION(POLYGON((0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0)),POINT(1 1 1))", 0, 0, 0, 0);
189 // printf("TWKB: %s\n",s);
190 ASSERT_STRING_EQUAL(s,"070801020308010105000000000200020000000100010000010801020202");
191
192 cu_twkb("GEOMETRYCOLLECTION EMPTY", 0, 0, 0, 0);
193 ASSERT_STRING_EQUAL(s,"0710");
194}
195
196static void test_twkb_out_idlist(void)
197{
198 int64_t idlist[2];
199
200 idlist[0] = 2;
201 idlist[1] = 4;
202 cu_twkb_idlist("MULTIPOINT(1 1, 0 0)",idlist, 0, 0, 0, 0);
203 // printf("TWKB: %s\n",s);
204 // printf("WKT: %s\n",w);
205 ASSERT_STRING_EQUAL(s,"040402040802020101");
206 ASSERT_STRING_EQUAL(w,"MULTIPOINT(1 1,0 0)");
207
208 /*
209 04 06 multipoint, size/idlist
210 07 size 7 bytes
211 02 two geometries
212 0408 idlist (2, 4)
213 0202 first point @ 1,1
214 0101 second point offset -1,-1
215 */
216 idlist[0] = 2;
217 idlist[1] = 4;
218 cu_twkb_idlist("MULTIPOINT(1 1, 0 0)",idlist, 0, 0, 0, TWKB_SIZE);
219 // printf("TWKB: %s\n",s);
220 // printf("WKT: %s\n",w);
221 ASSERT_STRING_EQUAL(s,"04060702040802020101");
222 ASSERT_STRING_EQUAL(w,"MULTIPOINT(1 1,0 0)");
223
224 /*
225 04 07 multipoint, bbox/size/idlist
226 0B size 11 bytes
227 00020002 bbox x(0,1), y(0,1)
228 02 two geometries
229 0408 idlist (2,4)
230 0202 first point @ 1,1
231 0101 seconds point offset -1,-1
232 */
233 idlist[0] = 2;
234 idlist[1] = 4;
235 cu_twkb_idlist("MULTIPOINT(1 1, 0 0)",idlist, 0, 0, 0, TWKB_SIZE | TWKB_BBOX);
236 // printf("TWKB: %s\n",s);
237 // printf("WKT: %s\n",w);
238 ASSERT_STRING_EQUAL(s,"04070B0002000202040802020101");
239 ASSERT_STRING_EQUAL(w,"MULTIPOINT(1 1,0 0)");
240
241 /*
242 0704 geometrycollection, idlist
243 02 two geometries
244 0408 idlist (2,4)
245 01000202 first point (type, meta, x, y)
246 01000000 second point (type, meta, x, y)
247 */
248 idlist[0] = 2;
249 idlist[1] = 4;
250 cu_twkb_idlist("GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))",idlist, 0, 0, 0, 0);
251 // printf("TWKB: %s\n",s);
252 ASSERT_STRING_EQUAL(s,"07040204080100020201000000");
253 ASSERT_STRING_EQUAL(w,"GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))");
254
255 /*
256 0706 geometrycollection, size/idlist
257 0D size, 13 bytes
258 02 two geometries
259 0408 idlist (2,4)
260 0102020202 first point (type, meta, size, x, y)
261 0102020000 second point (type, meta, size, x, y)
262 */
263 idlist[0] = 2;
264 idlist[1] = 4;
265 cu_twkb_idlist("GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))",idlist, 0, 0, 0, TWKB_SIZE);
266 // printf("TWKB: %s\n",s);
267 ASSERT_STRING_EQUAL(s,"07060D02040801020202020102020000");
268 ASSERT_STRING_EQUAL(w,"GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))");
269
270}
271
272
273/*
274** Used by test harness to register the tests in this file.
275*/
276void twkb_out_suite_setup(void);
static uint8_t variant
Definition cu_in_twkb.c:26
static void cu_twkb_idlist(char *wkt, int64_t *idlist, int8_t prec_xy, int8_t prec_z, int8_t prec_m, uint8_t variant)
Definition cu_out_twkb.c:70
static void test_twkb_out_polygon(void)
static void cu_twkb(char *wkt, int8_t prec_xy, int8_t prec_z, int8_t prec_m, uint8_t variant)
Definition cu_out_twkb.c:55
static int init_twkb_out_suite(void)
Definition cu_out_twkb.c:31
static void test_twkb_out_multipolygon(void)
static char * w
Definition cu_out_twkb.c:25
static void test_twkb_out_multipoint(void)
void twkb_out_suite_setup(void)
static void test_twkb_out_point(void)
Definition cu_out_twkb.c:88
static char * s
Definition cu_out_twkb.c:24
static void test_twkb_out_multilinestring(void)
static void test_twkb_out_idlist(void)
static void test_twkb_out_linestring(void)
static int clean_twkb_out_suite(void)
Definition cu_out_twkb.c:42
static void test_twkb_out_collection(void)
#define PG_ADD_TEST(suite, testfunc)
#define ASSERT_STRING_EQUAL(o, e)
#define LWVARHDRSZ
Definition liblwgeom.h:311
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
#define LW_PARSER_CHECK_NONE
Definition liblwgeom.h:2149
#define LWSIZE_GET(varsize)
Macro for reading the size from the GSERIALIZED size attribute.
Definition liblwgeom.h:324
char * hexbytes_from_bytes(const uint8_t *bytes, size_t size)
Definition lwout_wkb.c:40
char * lwgeom_to_ewkt(const LWGEOM *lwgeom)
Return an allocated string.
Definition lwgeom.c:593
LWGEOM * lwgeom_from_twkb(const uint8_t *twkb, size_t twkb_size, char check)
WKB inputs must have a declared size, to prevent malformed WKB from reading off the end of the memory...
Definition lwin_twkb.c:654
lwvarlena_t * lwgeom_to_twkb_with_idlist(const LWGEOM *geom, int64_t *idlist, uint8_t variant, int8_t precision_xy, int8_t precision_z, int8_t precision_m)
Convert LWGEOM to a char* in TWKB format.
Definition lwout_twkb.c:589
#define TWKB_SIZE
Definition liblwgeom.h:2228
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition lwin_wkt.c:940
#define TWKB_BBOX
Definition liblwgeom.h:2227
lwvarlena_t * lwgeom_to_twkb(const LWGEOM *geom, uint8_t variant, int8_t precision_xy, int8_t precision_z, int8_t precision_m)
Definition lwout_twkb.c:636
void lwnotice(const char *fmt,...) __attribute__((format(printf
Write a notice out to the notice handler.
void free(void *)
uint32_t size
Definition liblwgeom.h:307
char data[]
Definition liblwgeom.h:308