PostGIS 3.0.6dev-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 re-used 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 size_t twkb_size;
59 uint8_t *twkb;
60 if ( ! g ) lwnotice("input wkt is invalid: %s", wkt);
61 twkb = lwgeom_to_twkb(g, variant, prec_xy, prec_z, prec_m, &twkb_size);
62 lwgeom_free(g);
63 if ( s ) free(s);
64 s = hexbytes_from_bytes(twkb, twkb_size);
65 free(twkb);
66}
67
68
69/*
70** Creating an input TWKB from a wkt string
71*/
72static void cu_twkb_idlist(char *wkt, int64_t *idlist, int8_t prec_xy, int8_t prec_z, int8_t prec_m, uint8_t variant)
73{
75 LWGEOM *g_b;
76 size_t twkb_size;
77 uint8_t *twkb;
78 if ( ! g ) lwnotice("input wkt is invalid: %s", wkt);
79 twkb = lwgeom_to_twkb_with_idlist(g, idlist, variant, prec_xy, prec_z, prec_m, &twkb_size);
80 lwgeom_free(g);
81 if ( s ) free(s);
82 if ( w ) free(w);
83 s = hexbytes_from_bytes(twkb, twkb_size);
84 g_b = lwgeom_from_twkb(twkb, twkb_size, LW_PARSER_CHECK_NONE);
85 w = lwgeom_to_ewkt(g_b);
86 lwgeom_free(g_b);
87 free(twkb);
88}
89
90
91
92static void test_twkb_out_point(void)
93{
94
95 cu_twkb("POINT EMPTY", 0, 0, 0, 0);
96 CU_ASSERT_STRING_EQUAL(s,"0110");
97
98 cu_twkb("POINT(0 0)", 0, 0, 0, 0);
99 CU_ASSERT_STRING_EQUAL(s,"01000000");
100
101 cu_twkb("POINT(0 0 0 0)", 0, 0, 0, 0);
102 CU_ASSERT_STRING_EQUAL(s,"01080300000000");
103
104 /* Point with bounding box */
105 cu_twkb("POINT(0 0)", 0, 0, 0, TWKB_BBOX);
106 CU_ASSERT_STRING_EQUAL(s,"0101000000000000");
107 // printf("TWKB: %s\n",s);
108
109 /* Adding a size paramters to X/Y */
110 cu_twkb("POINT(0 0)", 0, 0, 0, TWKB_SIZE);
111 CU_ASSERT_STRING_EQUAL(s,"0102020000");
112
113 /* Adding a size paramters to X/Y/M */
114 cu_twkb("POINTM(0 0 0)", 0, 0, 0, TWKB_SIZE);
115 CU_ASSERT_STRING_EQUAL(s,"010A0203000000");
116
117 /* Adding a size paramters to X/Y/Z/M */
118 cu_twkb("POINT(0 0 0 0)", 0, 0, 0, TWKB_SIZE);
119 CU_ASSERT_STRING_EQUAL(s,"010A030400000000");
120
121 /* Since the third dimension is Z it shall get a precision of 1 decimal (third argument) */
122 cu_twkb("POINTZ(1 1 1)", 0,1,2, 0);
123 CU_ASSERT_STRING_EQUAL(s,"010845020214");
124
125 /* Since the third dimension is M it shall get a precision of 2 decimals (fourth argument) */
126 cu_twkb("POINTM(1 1 1)", 0,1,2, 0);
127 // printf("\n%s\n", s);
128 CU_ASSERT_STRING_EQUAL(s,"0108460202C801");
129}
130
132{
133
134 cu_twkb("LINESTRING(0 0,1 1)", 0, 0, 0, 0);
135 CU_ASSERT_STRING_EQUAL(s,"02000200000202");
136 // printf("TWKB: %s\n",s);
137
138 cu_twkb("LINESTRING(0 0 1,1 1 2,2 2 3)", 0, 0, 0, 0);
139 CU_ASSERT_STRING_EQUAL(s,"02080103000002020202020202");
140 // printf("TWKB: %s\n",s);
141
142 /* Line with bounding box */
143 cu_twkb("LINESTRING(0 0,1 1,2 2)", 0, 0, 0, TWKB_BBOX);
144 CU_ASSERT_STRING_EQUAL(s,"02010004000403000002020202");
145 // printf("TWKB: %s\n",s);
146
147 cu_twkb("LINESTRING EMPTY", 0, 0, 0, 0);
148 CU_ASSERT_STRING_EQUAL(s,"0210");
149 // printf("TWKB: %s\n",s);
150}
151
152static void test_twkb_out_polygon(void)
153{
154 cu_twkb("SRID=4;POLYGON((0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0))", 0, 0, 0, 0);
155 CU_ASSERT_STRING_EQUAL(s,"0308010105000000000200020000000100010000");
156 // printf("TWKB: %s\n",s);
157
158 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);
159 CU_ASSERT_STRING_EQUAL(s,"03080301050000000200020002020000020001000201000002");
160 // printf("TWKB: %s\n",s);
161
162 cu_twkb("POLYGON EMPTY", 0, 0, 0, 0);
163 CU_ASSERT_STRING_EQUAL(s,"0310");
164 // printf("TWKB: %s\n",s);
165}
166
168{
169 cu_twkb("MULTIPOINT(0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0)", 0, 0, 0, 0);
170 CU_ASSERT_STRING_EQUAL(s,"04080105000000000200020000000100010000");
171
172 cu_twkb("MULTIPOINT(0 0 0, 0.26794919243112270647255365849413 1 3)",7 ,7 , 0, 0);
173 //printf("WKB: %s",s);
174 CU_ASSERT_STRING_EQUAL(s,"E4081D02000000888BC70280DAC409808ECE1C");
175// printf("TWKB: %s\n",s);
176}
177
179
181{
182 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);
183 CU_ASSERT_STRING_EQUAL(s,"060801020105000000000200020000000100010000020501010000060006000000050005000005020200000200020000000100010000");
184}
185
187{
188 cu_twkb("GEOMETRYCOLLECTION(LINESTRING(1 1, 2 2), LINESTRING(3 3, 4 4), LINESTRING(5 5, 6 6))", 0, 0, 0, 0);
189 // printf("TWKB: %s\n",s);
190 CU_ASSERT_STRING_EQUAL(s,"07000302000202020202020002060602020200020A0A0202");
191
192 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);
193 // printf("TWKB: %s\n",s);
194 CU_ASSERT_STRING_EQUAL(s,"070801020308010105000000000200020000000100010000010801020202");
195
196 cu_twkb("GEOMETRYCOLLECTION EMPTY", 0, 0, 0, 0);
197 CU_ASSERT_STRING_EQUAL(s,"0710");
198}
199
200static void test_twkb_out_idlist(void)
201{
202 int64_t idlist[2];
203
204 idlist[0] = 2;
205 idlist[1] = 4;
206 cu_twkb_idlist("MULTIPOINT(1 1, 0 0)",idlist, 0, 0, 0, 0);
207 // printf("TWKB: %s\n",s);
208 // printf("WKT: %s\n",w);
209 CU_ASSERT_STRING_EQUAL(s,"040402040802020101");
210 CU_ASSERT_STRING_EQUAL(w,"MULTIPOINT(1 1,0 0)");
211
212 /*
213 04 06 multipoint, size/idlist
214 07 size 7 bytes
215 02 two geometries
216 0408 idlist (2, 4)
217 0202 first point @ 1,1
218 0101 second point offset -1,-1
219 */
220 idlist[0] = 2;
221 idlist[1] = 4;
222 cu_twkb_idlist("MULTIPOINT(1 1, 0 0)",idlist, 0, 0, 0, TWKB_SIZE);
223 // printf("TWKB: %s\n",s);
224 // printf("WKT: %s\n",w);
225 CU_ASSERT_STRING_EQUAL(s,"04060702040802020101");
226 CU_ASSERT_STRING_EQUAL(w,"MULTIPOINT(1 1,0 0)");
227
228 /*
229 04 07 multipoint, bbox/size/idlist
230 0B size 11 bytes
231 00020002 bbox x(0,1), y(0,1)
232 02 two geometries
233 0408 idlist (2,4)
234 0202 first point @ 1,1
235 0101 seconds point offset -1,-1
236 */
237 idlist[0] = 2;
238 idlist[1] = 4;
239 cu_twkb_idlist("MULTIPOINT(1 1, 0 0)",idlist, 0, 0, 0, TWKB_SIZE | TWKB_BBOX);
240 // printf("TWKB: %s\n",s);
241 // printf("WKT: %s\n",w);
242 CU_ASSERT_STRING_EQUAL(s,"04070B0002000202040802020101");
243 CU_ASSERT_STRING_EQUAL(w,"MULTIPOINT(1 1,0 0)");
244
245 /*
246 0704 geometrycollection, idlist
247 02 two geometries
248 0408 idlist (2,4)
249 01000202 first point (type, meta, x, y)
250 01000000 second point (type, meta, x, y)
251 */
252 idlist[0] = 2;
253 idlist[1] = 4;
254 cu_twkb_idlist("GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))",idlist, 0, 0, 0, 0);
255 // printf("TWKB: %s\n",s);
256 CU_ASSERT_STRING_EQUAL(s,"07040204080100020201000000");
257 CU_ASSERT_STRING_EQUAL(w,"GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))");
258
259 /*
260 0706 geometrycollection, size/idlist
261 0D size, 13 bytes
262 02 two geometries
263 0408 idlist (2,4)
264 0102020202 first point (type, meta, size, x, y)
265 0102020000 second point (type, meta, size, x, y)
266 */
267 idlist[0] = 2;
268 idlist[1] = 4;
269 cu_twkb_idlist("GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))",idlist, 0, 0, 0, TWKB_SIZE);
270 // printf("TWKB: %s\n",s);
271 CU_ASSERT_STRING_EQUAL(s,"07060D02040801020202020102020000");
272 CU_ASSERT_STRING_EQUAL(w,"GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))");
273
274}
275
276
277/*
278** Used by test harness to register the tests in this file.
279*/
280void 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:72
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:92
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)
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1138
#define LW_PARSER_CHECK_NONE
Definition liblwgeom.h:2060
uint8_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, size_t *twkb_size)
Convert LWGEOM to a char* in TWKB format.
Definition lwout_twkb.c:589
char * hexbytes_from_bytes(const uint8_t *bytes, size_t size)
Definition lwout_wkb.c:39
char * lwgeom_to_ewkt(const LWGEOM *lwgeom)
Return an alloced string.
Definition lwgeom.c:547
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
uint8_t * lwgeom_to_twkb(const LWGEOM *geom, uint8_t variant, int8_t precision_xy, int8_t precision_z, int8_t precision_m, size_t *twkb_size)
Definition lwout_twkb.c:636
#define TWKB_SIZE
Definition liblwgeom.h:2139
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition lwin_wkt.c:905
#define TWKB_BBOX
Definition liblwgeom.h:2138
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition lwutil.c:177
void free(void *)