1 /*
2
3 GeoPackage extensions for SpatiaLite / SQLite
4
5 Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
7 The contents of this file are subject to the Mozilla Public License Version
8 1.1 (the "License"); you may not use this file except in compliance with
9 the License. You may obtain a copy of the License at
10 http://www.mozilla.org/MPL/
11
12 Software distributed under the License is distributed on an "AS IS" basis,
13 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 for the specific language governing rights and limitations under the
15 License.
16
17 The Original Code is GeoPackage Extensions
18
19 The Initial Developer of the Original Code is Brad Hards (bradh@frogmouth.net)
20
21 Portions created by the Initial Developer are Copyright (C) 2012-2015
22 the Initial Developer. All Rights Reserved.
23
24 Contributor(s):
25
26 Alternatively, the contents of this file may be used under the terms of
27 either the GNU General Public License Version 2 or later (the "GPL"), or
28 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 in which case the provisions of the GPL or the LGPL are applicable instead
30 of those above. If you wish to allow use of your version of this file only
31 under the terms of either the GPL or the LGPL, and not to allow others to
32 use your version of this file under the terms of the MPL, indicate your
33 decision by deleting the provisions above and replace them with the notice
34 and other provisions required by the GPL or the LGPL. If you do not delete
35 the provisions above, a recipient may use your version of this file under
36 the terms of any one of the MPL, the GPL or the LGPL.
37
38 */
39
40 #include "spatialite/geopackage.h"
41 #include "geopackage_internal.h"
42
43 #if defined(_WIN32) && !defined(__MINGW32__)
44 #include "config-msvc.h"
45 #else
46 #include "config.h"
47 #endif
48
49 #ifdef ENABLE_GEOPACKAGE
50
51 #define GEOPACKAGE_UNUSED() if (argc || argv) argc = argc;
52
53 static void
gpkgMakePoint(double x,double y,int srid,unsigned char ** result,unsigned int * size)54 gpkgMakePoint (double x, double y, int srid, unsigned char **result,
55 unsigned int *size)
56 {
57 /* build a Blob encoded Geometry representing a POINT */
58 unsigned char *ptr;
59 int endian_arch = gaiaEndianArch ();
60
61 /* computing the Blob size and then allocating it */
62 *size = GEOPACKAGE_HEADER_LEN + GEOPACKAGE_2D_ENVELOPE_LEN;
63 *size += GEOPACKAGE_WKB_HEADER_LEN;
64 *size += (sizeof (double) * 2); /* [x,y] coords */
65 *result = malloc (*size);
66 if (*result == NULL)
67 {
68 return;
69 }
70 memset (*result, 0xD9, *size);
71 ptr = *result;
72
73 /* setting the Blob value */
74 gpkgSetHeader2DLittleEndian (ptr, srid, endian_arch);
75
76 gpkgSetHeader2DMbr (ptr + GEOPACKAGE_HEADER_LEN, x, y, x, y, endian_arch);
77
78 *(ptr + GEOPACKAGE_HEADER_LEN +
79 GEOPACKAGE_2D_ENVELOPE_LEN) = GEOPACKAGE_WKB_LITTLEENDIAN;
80 gaiaExport32 (ptr +
81 GEOPACKAGE_HEADER_LEN +
82 GEOPACKAGE_2D_ENVELOPE_LEN
83 + 1, GEOPACKAGE_WKB_POINT, 1, endian_arch);
84 gaiaExport64 (ptr +
85 GEOPACKAGE_HEADER_LEN +
86 GEOPACKAGE_2D_ENVELOPE_LEN
87 + GEOPACKAGE_WKB_HEADER_LEN, x, 1, endian_arch);
88 gaiaExport64 (ptr +
89 GEOPACKAGE_HEADER_LEN +
90 GEOPACKAGE_2D_ENVELOPE_LEN
91 +
92 GEOPACKAGE_WKB_HEADER_LEN
93 + sizeof (double), y, 1, endian_arch);
94 }
95
96 static void
gpkgMakePointZ(double x,double y,double z,int srid,unsigned char ** result,unsigned int * size)97 gpkgMakePointZ (double x, double y, double z, int srid, unsigned char **result,
98 unsigned int *size)
99 {
100 /* build a Blob encoded Geometry representing a POINT */
101 unsigned char *ptr;
102 int endian_arch = gaiaEndianArch ();
103 /* computing the Blob size and then allocating it */
104 *size = GEOPACKAGE_HEADER_LEN + GEOPACKAGE_3D_ENVELOPE_LEN;
105 *size += GEOPACKAGE_WKB_HEADER_LEN;
106 *size += (sizeof (double) * 3); /* [x,y,z] coords */
107 *result = malloc (*size);
108 if (*result == NULL)
109 {
110 return;
111 }
112 memset (*result, 0xD9, *size); /* just a flag value */
113 ptr = *result;
114 /* setting the Blob value */
115 *ptr = GEOPACKAGE_MAGIC1;
116 *(ptr + 1) = GEOPACKAGE_MAGIC2;
117 *(ptr + 2) = GEOPACKAGE_VERSION;
118 *(ptr + 3) = GEOPACKAGE_FLAGS_3D_LITTLEENDIAN;
119 gaiaExport32 (ptr + 4, srid, 1, endian_arch); /* the SRID */
120 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN, x, 1, endian_arch); /* MBR - minimum X */
121 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + sizeof (double), x, 1, endian_arch); /* MBR - maximum x */
122 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 2 * sizeof (double), y, 1, endian_arch); /* MBR - minimum Y */
123 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 3 * sizeof (double), y, 1, endian_arch); /* MBR - maximum Y */
124 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 4 * sizeof (double), z, 1, endian_arch); /* MBR - maximum Z */
125 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 5 * sizeof (double), z, 1, endian_arch); /* MBR - maximum Z */
126 *(ptr + GEOPACKAGE_HEADER_LEN +
127 GEOPACKAGE_3D_ENVELOPE_LEN) = GEOPACKAGE_WKB_LITTLEENDIAN;
128 gaiaExport32 (ptr +
129 GEOPACKAGE_HEADER_LEN +
130 GEOPACKAGE_3D_ENVELOPE_LEN
131 + 1, GEOPACKAGE_WKB_POINTZ, 1, endian_arch);
132 gaiaExport64 (ptr +
133 GEOPACKAGE_HEADER_LEN +
134 GEOPACKAGE_3D_ENVELOPE_LEN
135 + GEOPACKAGE_WKB_HEADER_LEN, x, 1, endian_arch);
136 gaiaExport64 (ptr +
137 GEOPACKAGE_HEADER_LEN +
138 GEOPACKAGE_3D_ENVELOPE_LEN
139 +
140 GEOPACKAGE_WKB_HEADER_LEN
141 + sizeof (double), y, 1, endian_arch);
142 gaiaExport64 (ptr +
143 GEOPACKAGE_HEADER_LEN +
144 GEOPACKAGE_3D_ENVELOPE_LEN
145 +
146 GEOPACKAGE_WKB_HEADER_LEN
147 + (2 * sizeof (double)), z, 1, endian_arch);
148 }
149
150 static void
gpkgMakePointM(double x,double y,double m,int srid,unsigned char ** result,unsigned int * size)151 gpkgMakePointM (double x, double y, double m, int srid, unsigned char **result,
152 unsigned int *size)
153 {
154 /* build a Blob encoded Geometry representing a POINT */
155 unsigned char *ptr;
156 int endian_arch = gaiaEndianArch ();
157 /* computing the Blob size and then allocating it */
158 *size = GEOPACKAGE_HEADER_LEN + GEOPACKAGE_3D_ENVELOPE_LEN;
159 *size += GEOPACKAGE_WKB_HEADER_LEN;
160 *size += (sizeof (double) * 3); /* [x,y,m] coords */
161 *result = malloc (*size);
162 if (*result == NULL)
163 {
164 return;
165 }
166 memset (*result, 0xD9, *size); /* just a flag value */
167 ptr = *result;
168 /* setting the Blob value */
169 *ptr = GEOPACKAGE_MAGIC1;
170 *(ptr + 1) = GEOPACKAGE_MAGIC2;
171 *(ptr + 2) = GEOPACKAGE_VERSION;
172 *(ptr + 3) = GEOPACKAGE_FLAGS_2DM_LITTLEENDIAN;
173 gaiaExport32 (ptr + 4, srid, 1, endian_arch); /* the SRID */
174 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN, x, 1, endian_arch); /* MBR - minimum X */
175 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + sizeof (double), x, 1, endian_arch); /* MBR - maximum X */
176 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 2 * sizeof (double), y, 1, endian_arch); /* MBR - minimum Y */
177 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 3 * sizeof (double), y, 1, endian_arch); /* MBR - maximum Y */
178 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 4 * sizeof (double), m, 1, endian_arch); /* MBR - maximum M */
179 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 5 * sizeof (double), m, 1, endian_arch); /* MBR - maximum M */
180 *(ptr + GEOPACKAGE_HEADER_LEN +
181 GEOPACKAGE_3D_ENVELOPE_LEN) = GEOPACKAGE_WKB_LITTLEENDIAN;
182 gaiaExport32 (ptr +
183 GEOPACKAGE_HEADER_LEN +
184 GEOPACKAGE_3D_ENVELOPE_LEN
185 + 1, GEOPACKAGE_WKB_POINTM, 1, endian_arch);
186 gaiaExport64 (ptr +
187 GEOPACKAGE_HEADER_LEN +
188 GEOPACKAGE_3D_ENVELOPE_LEN
189 + GEOPACKAGE_WKB_HEADER_LEN, x, 1, endian_arch);
190 gaiaExport64 (ptr +
191 GEOPACKAGE_HEADER_LEN +
192 GEOPACKAGE_3D_ENVELOPE_LEN
193 +
194 GEOPACKAGE_WKB_HEADER_LEN
195 + sizeof (double), y, 1, endian_arch);
196 gaiaExport64 (ptr +
197 GEOPACKAGE_HEADER_LEN +
198 GEOPACKAGE_3D_ENVELOPE_LEN
199 +
200 GEOPACKAGE_WKB_HEADER_LEN
201 + (2 * sizeof (double)), m, 1, endian_arch);
202 }
203
204 static void
gpkgMakePointZM(double x,double y,double z,double m,int srid,unsigned char ** result,unsigned int * size)205 gpkgMakePointZM (double x, double y, double z, double m, int srid,
206 unsigned char **result, unsigned int *size)
207 {
208 /* build a Blob encoded Geometry representing a POINT */
209 unsigned char *ptr;
210 int endian_arch = gaiaEndianArch ();
211 /* computing the Blob size and then allocating it */
212 *size = GEOPACKAGE_HEADER_LEN + GEOPACKAGE_4D_ENVELOPE_LEN;
213 *size += GEOPACKAGE_WKB_HEADER_LEN;
214 *size += (sizeof (double) * 4); /* [x,y,z,m] coords */
215 *result = malloc (*size);
216 if (*result == NULL)
217 {
218 return;
219 }
220 memset (*result, 0xD9, *size); /* just a flag value */
221 ptr = *result;
222 /* setting the Blob value */
223 *ptr = GEOPACKAGE_MAGIC1;
224 *(ptr + 1) = GEOPACKAGE_MAGIC2;
225 *(ptr + 2) = GEOPACKAGE_VERSION;
226 *(ptr + 3) = GEOPACKAGE_FLAGS_3DM_LITTLEENDIAN;
227 gaiaExport32 (ptr + 4, srid, 1, endian_arch); /* the SRID */
228 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN, x, 1, endian_arch); /* MBR - minimum X */
229 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 1 * sizeof (double), x, 1, endian_arch); /* MBR - maximum X */
230 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 2 * sizeof (double), y, 1, endian_arch); /* MBR - minimum Y */
231 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 3 * sizeof (double), y, 1, endian_arch); /* MBR - maximum Y */
232 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 4 * sizeof (double), z, 1, endian_arch); /* MBR - minimum Z */
233 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 5 * sizeof (double), z, 1, endian_arch); /* MBR - maximum Z */
234 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 6 * sizeof (double), m, 1, endian_arch); /* MBR - minimum M */
235 gaiaExport64 (ptr + GEOPACKAGE_HEADER_LEN + 7 * sizeof (double), m, 1, endian_arch); /* MBR - maximum M */
236 *(ptr + GEOPACKAGE_HEADER_LEN +
237 GEOPACKAGE_4D_ENVELOPE_LEN) = GEOPACKAGE_WKB_LITTLEENDIAN;
238 gaiaExport32 (ptr +
239 GEOPACKAGE_HEADER_LEN +
240 GEOPACKAGE_4D_ENVELOPE_LEN
241 + 1, GEOPACKAGE_WKB_POINTZM, 1, endian_arch);
242 gaiaExport64 (ptr +
243 GEOPACKAGE_HEADER_LEN +
244 GEOPACKAGE_4D_ENVELOPE_LEN
245 + GEOPACKAGE_WKB_HEADER_LEN, x, 1, endian_arch);
246 gaiaExport64 (ptr +
247 GEOPACKAGE_HEADER_LEN +
248 GEOPACKAGE_4D_ENVELOPE_LEN
249 +
250 GEOPACKAGE_WKB_HEADER_LEN
251 + sizeof (double), y, 1, endian_arch);
252 gaiaExport64 (ptr +
253 GEOPACKAGE_HEADER_LEN +
254 GEOPACKAGE_4D_ENVELOPE_LEN
255 +
256 GEOPACKAGE_WKB_HEADER_LEN
257 + (2 * sizeof (double)), z, 1, endian_arch);
258 gaiaExport64 (ptr +
259 GEOPACKAGE_HEADER_LEN +
260 GEOPACKAGE_4D_ENVELOPE_LEN
261 +
262 GEOPACKAGE_WKB_HEADER_LEN
263 + (3 * sizeof (double)), m, 1, endian_arch);
264 }
265
266 GEOPACKAGE_PRIVATE void
fnct_gpkgMakePoint(sqlite3_context * context,int argc UNUSED,sqlite3_value ** argv)267 fnct_gpkgMakePoint (sqlite3_context * context, int argc UNUSED,
268 sqlite3_value ** argv)
269 {
270 /* SQL function:
271 / gpkgMakePoint(x, y)
272 /
273 / Creates a GeoPackage geometry POINT
274 /
275 / returns nothing on success, raises exception on error
276 */
277 unsigned int len;
278 int int_value;
279 unsigned char *p_result = NULL;
280 double x;
281 double y;
282 GEOPACKAGE_UNUSED (); /* LCOV_EXCL_LINE */
283 if (sqlite3_value_type (argv[0]) == SQLITE_FLOAT)
284 {
285 x = sqlite3_value_double (argv[0]);
286 }
287 else if (sqlite3_value_type (argv[0]) == SQLITE_INTEGER)
288 {
289 int_value = sqlite3_value_int (argv[0]);
290 x = int_value;
291 }
292 else
293 {
294 sqlite3_result_null (context);
295 return;
296 }
297 if (sqlite3_value_type (argv[1]) == SQLITE_FLOAT)
298 {
299 y = sqlite3_value_double (argv[1]);
300 }
301 else if (sqlite3_value_type (argv[1]) == SQLITE_INTEGER)
302 {
303 int_value = sqlite3_value_int (argv[1]);
304 y = int_value;
305 }
306 else
307 {
308 sqlite3_result_null (context);
309 return;
310 }
311 gpkgMakePoint (x, y, GEOPACKAGE_DEFAULT_UNDEFINED_SRID, &p_result, &len);
312 if (!p_result)
313 {
314 sqlite3_result_null (context);
315 }
316 else
317 {
318 sqlite3_result_blob (context, p_result, len, free);
319 }
320 }
321
322 GEOPACKAGE_PRIVATE void
fnct_gpkgMakePointWithSRID(sqlite3_context * context,int argc UNUSED,sqlite3_value ** argv)323 fnct_gpkgMakePointWithSRID (sqlite3_context * context, int argc UNUSED,
324 sqlite3_value ** argv)
325 {
326 /* SQL function:
327 / gpkgMakePoint(x, y, srid)
328 /
329 / Creates a GeoPackage geometry POINT
330 /
331 / returns nothing on success, raises exception on error
332 */
333 unsigned int len;
334 int int_value;
335 unsigned char *p_result = NULL;
336 double x;
337 double y;
338 int srid;
339 GEOPACKAGE_UNUSED (); /* LCOV_EXCL_LINE */
340 if (sqlite3_value_type (argv[0]) == SQLITE_FLOAT)
341 {
342 x = sqlite3_value_double (argv[0]);
343 }
344 else if (sqlite3_value_type (argv[0]) == SQLITE_INTEGER)
345 {
346 int_value = sqlite3_value_int (argv[0]);
347 x = int_value;
348 }
349 else
350 {
351 sqlite3_result_null (context);
352 return;
353 }
354 if (sqlite3_value_type (argv[1]) == SQLITE_FLOAT)
355 {
356 y = sqlite3_value_double (argv[1]);
357 }
358 else if (sqlite3_value_type (argv[1]) == SQLITE_INTEGER)
359 {
360 int_value = sqlite3_value_int (argv[1]);
361 y = int_value;
362 }
363 else
364 {
365 sqlite3_result_null (context);
366 return;
367 }
368 if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
369 {
370 sqlite3_result_null (context);
371 return;
372 }
373 srid = sqlite3_value_int (argv[2]);
374
375 gpkgMakePoint (x, y, srid, &p_result, &len);
376 if (!p_result)
377 {
378 sqlite3_result_null (context);
379 }
380 else
381 {
382 sqlite3_result_blob (context, p_result, len, free);
383 }
384 }
385
386 GEOPACKAGE_PRIVATE void
fnct_gpkgMakePointZ(sqlite3_context * context,int argc UNUSED,sqlite3_value ** argv)387 fnct_gpkgMakePointZ (sqlite3_context * context, int argc UNUSED,
388 sqlite3_value ** argv)
389 {
390 /* SQL function:
391 / gpkgMakePointZ(x, y, z)
392 /
393 / Creates a GeoPackage geometry POINT Z
394 /
395 / returns nothing on success, raises exception on error
396 */
397 unsigned int len;
398 int int_value;
399 unsigned char *p_result = NULL;
400 double x;
401 double y;
402 double z;
403 GEOPACKAGE_UNUSED (); /* LCOV_EXCL_LINE */
404 if (sqlite3_value_type (argv[0]) == SQLITE_FLOAT)
405 {
406 x = sqlite3_value_double (argv[0]);
407 }
408 else if (sqlite3_value_type (argv[0]) == SQLITE_INTEGER)
409 {
410 int_value = sqlite3_value_int (argv[0]);
411 x = int_value;
412 }
413 else
414 {
415 sqlite3_result_null (context);
416 return;
417 }
418 if (sqlite3_value_type (argv[1]) == SQLITE_FLOAT)
419 {
420 y = sqlite3_value_double (argv[1]);
421 }
422 else if (sqlite3_value_type (argv[1]) == SQLITE_INTEGER)
423 {
424 int_value = sqlite3_value_int (argv[1]);
425 y = int_value;
426 }
427 else
428 {
429 sqlite3_result_null (context);
430 return;
431 }
432 if (sqlite3_value_type (argv[2]) == SQLITE_FLOAT)
433 {
434 z = sqlite3_value_double (argv[2]);
435 }
436 else if (sqlite3_value_type (argv[2]) == SQLITE_INTEGER)
437 {
438 int_value = sqlite3_value_int (argv[2]);
439 z = int_value;
440 }
441 else
442 {
443 sqlite3_result_null (context);
444 return;
445 }
446
447 gpkgMakePointZ (x, y, z,
448 GEOPACKAGE_DEFAULT_UNDEFINED_SRID, &p_result, &len);
449 if (!p_result)
450 {
451 sqlite3_result_null (context);
452 }
453 else
454 {
455 sqlite3_result_blob (context, p_result, len, free);
456 }
457 }
458
459 GEOPACKAGE_PRIVATE void
fnct_gpkgMakePointZWithSRID(sqlite3_context * context,int argc UNUSED,sqlite3_value ** argv)460 fnct_gpkgMakePointZWithSRID (sqlite3_context * context, int argc UNUSED,
461 sqlite3_value ** argv)
462 {
463 /* SQL function:
464 / gpkgMakePointZ(x, y, z, srid)
465 /
466 / Creates a GeoPackage geometry POINT Z
467 /
468 / returns nothing on success, raises exception on error
469 */
470 unsigned int len;
471 int int_value;
472 unsigned char *p_result = NULL;
473 double x;
474 double y;
475 double z;
476 int srid;
477 GEOPACKAGE_UNUSED (); /* LCOV_EXCL_LINE */
478 if (sqlite3_value_type (argv[0]) == SQLITE_FLOAT)
479 {
480 x = sqlite3_value_double (argv[0]);
481 }
482 else if (sqlite3_value_type (argv[0]) == SQLITE_INTEGER)
483 {
484 int_value = sqlite3_value_int (argv[0]);
485 x = int_value;
486 }
487 else
488 {
489 sqlite3_result_null (context);
490 return;
491 }
492 if (sqlite3_value_type (argv[1]) == SQLITE_FLOAT)
493 {
494 y = sqlite3_value_double (argv[1]);
495 }
496 else if (sqlite3_value_type (argv[1]) == SQLITE_INTEGER)
497 {
498 int_value = sqlite3_value_int (argv[1]);
499 y = int_value;
500 }
501 else
502 {
503 sqlite3_result_null (context);
504 return;
505 }
506 if (sqlite3_value_type (argv[2]) == SQLITE_FLOAT)
507 {
508 z = sqlite3_value_double (argv[2]);
509 }
510 else if (sqlite3_value_type (argv[2]) == SQLITE_INTEGER)
511 {
512 int_value = sqlite3_value_int (argv[2]);
513 z = int_value;
514 }
515 else
516 {
517 sqlite3_result_null (context);
518 return;
519 }
520 if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
521 {
522 sqlite3_result_null (context);
523 return;
524 }
525 srid = sqlite3_value_int (argv[3]);
526
527 gpkgMakePointZ (x, y, z, srid, &p_result, &len);
528 if (!p_result)
529 {
530 sqlite3_result_null (context);
531 }
532 else
533 {
534 sqlite3_result_blob (context, p_result, len, free);
535 }
536 }
537
538 GEOPACKAGE_PRIVATE void
fnct_gpkgMakePointM(sqlite3_context * context,int argc UNUSED,sqlite3_value ** argv)539 fnct_gpkgMakePointM (sqlite3_context * context, int argc UNUSED,
540 sqlite3_value ** argv)
541 {
542 /* SQL function:
543 / gpkgMakePointM(x, y, m)
544 /
545 / Creates a GeoPackage geometry POINT M
546 /
547 / returns nothing on success, raises exception on error
548 */
549 unsigned int len;
550 int int_value;
551 unsigned char *p_result = NULL;
552 double x;
553 double y;
554 double m;
555 GEOPACKAGE_UNUSED (); /* LCOV_EXCL_LINE */
556 if (sqlite3_value_type (argv[0]) == SQLITE_FLOAT)
557 {
558 x = sqlite3_value_double (argv[0]);
559 }
560 else if (sqlite3_value_type (argv[0]) == SQLITE_INTEGER)
561 {
562 int_value = sqlite3_value_int (argv[0]);
563 x = int_value;
564 }
565 else
566 {
567 sqlite3_result_null (context);
568 return;
569 }
570 if (sqlite3_value_type (argv[1]) == SQLITE_FLOAT)
571 {
572 y = sqlite3_value_double (argv[1]);
573 }
574 else if (sqlite3_value_type (argv[1]) == SQLITE_INTEGER)
575 {
576 int_value = sqlite3_value_int (argv[1]);
577 y = int_value;
578 }
579 else
580 {
581 sqlite3_result_null (context);
582 return;
583 }
584 if (sqlite3_value_type (argv[2]) == SQLITE_FLOAT)
585 {
586 m = sqlite3_value_double (argv[2]);
587 }
588 else if (sqlite3_value_type (argv[2]) == SQLITE_INTEGER)
589 {
590 int_value = sqlite3_value_int (argv[2]);
591 m = int_value;
592 }
593 else
594 {
595 sqlite3_result_null (context);
596 return;
597 }
598
599 gpkgMakePointM (x, y, m,
600 GEOPACKAGE_DEFAULT_UNDEFINED_SRID, &p_result, &len);
601 if (!p_result)
602 {
603 sqlite3_result_null (context);
604 }
605 else
606 {
607 sqlite3_result_blob (context, p_result, len, free);
608 }
609 }
610
611 GEOPACKAGE_PRIVATE void
fnct_gpkgMakePointMWithSRID(sqlite3_context * context,int argc UNUSED,sqlite3_value ** argv)612 fnct_gpkgMakePointMWithSRID (sqlite3_context * context, int argc UNUSED,
613 sqlite3_value ** argv)
614 {
615 /* SQL function:
616 / gpkgMakePointM(x, y, m, srid)
617 /
618 / Creates a GeoPackage geometry POINT M
619 /
620 / returns nothing on success, raises exception on error
621 */
622 unsigned int len;
623 int int_value;
624 unsigned char *p_result = NULL;
625 double x;
626 double y;
627 double m;
628 int srid;
629 GEOPACKAGE_UNUSED (); /* LCOV_EXCL_LINE */
630 if (sqlite3_value_type (argv[0]) == SQLITE_FLOAT)
631 {
632 x = sqlite3_value_double (argv[0]);
633 }
634 else if (sqlite3_value_type (argv[0]) == SQLITE_INTEGER)
635 {
636 int_value = sqlite3_value_int (argv[0]);
637 x = int_value;
638 }
639 else
640 {
641 sqlite3_result_null (context);
642 return;
643 }
644 if (sqlite3_value_type (argv[1]) == SQLITE_FLOAT)
645 {
646 y = sqlite3_value_double (argv[1]);
647 }
648 else if (sqlite3_value_type (argv[1]) == SQLITE_INTEGER)
649 {
650 int_value = sqlite3_value_int (argv[1]);
651 y = int_value;
652 }
653 else
654 {
655 sqlite3_result_null (context);
656 return;
657 }
658 if (sqlite3_value_type (argv[2]) == SQLITE_FLOAT)
659 {
660 m = sqlite3_value_double (argv[2]);
661 }
662 else if (sqlite3_value_type (argv[2]) == SQLITE_INTEGER)
663 {
664 int_value = sqlite3_value_int (argv[2]);
665 m = int_value;
666 }
667 else
668 {
669 sqlite3_result_null (context);
670 return;
671 }
672 if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
673 {
674 sqlite3_result_null (context);
675 return;
676 }
677 srid = sqlite3_value_int (argv[3]);
678
679 gpkgMakePointM (x, y, m, srid, &p_result, &len);
680 if (!p_result)
681 {
682 sqlite3_result_null (context);
683 }
684 else
685 {
686 sqlite3_result_blob (context, p_result, len, free);
687 }
688 }
689
690 GEOPACKAGE_PRIVATE void
fnct_gpkgMakePointZM(sqlite3_context * context,int argc UNUSED,sqlite3_value ** argv)691 fnct_gpkgMakePointZM (sqlite3_context * context, int argc UNUSED,
692 sqlite3_value ** argv)
693 {
694 /* SQL function:
695 / gpkgMakePointM(x, y, z, m)
696 /
697 / Creates a GeoPackage geometry POINT ZM
698 /
699 / returns nothing on success, raises exception on error
700 */
701 unsigned int len;
702 int int_value;
703 unsigned char *p_result = NULL;
704 double x;
705 double y;
706 double z;
707 double m;
708 GEOPACKAGE_UNUSED (); /* LCOV_EXCL_LINE */
709 if (sqlite3_value_type (argv[0]) == SQLITE_FLOAT)
710 {
711 x = sqlite3_value_double (argv[0]);
712 }
713 else if (sqlite3_value_type (argv[0]) == SQLITE_INTEGER)
714 {
715 int_value = sqlite3_value_int (argv[0]);
716 x = int_value;
717 }
718 else
719 {
720 sqlite3_result_null (context);
721 return;
722 }
723 if (sqlite3_value_type (argv[1]) == SQLITE_FLOAT)
724 {
725 y = sqlite3_value_double (argv[1]);
726 }
727 else if (sqlite3_value_type (argv[1]) == SQLITE_INTEGER)
728 {
729 int_value = sqlite3_value_int (argv[1]);
730 y = int_value;
731 }
732 else
733 {
734 sqlite3_result_null (context);
735 return;
736 }
737 if (sqlite3_value_type (argv[2]) == SQLITE_FLOAT)
738 {
739 z = sqlite3_value_double (argv[2]);
740 }
741 else if (sqlite3_value_type (argv[2]) == SQLITE_INTEGER)
742 {
743 int_value = sqlite3_value_int (argv[2]);
744 z = int_value;
745 }
746 else
747 {
748 sqlite3_result_null (context);
749 return;
750 }
751 if (sqlite3_value_type (argv[3]) == SQLITE_FLOAT)
752 {
753 m = sqlite3_value_double (argv[3]);
754 }
755 else if (sqlite3_value_type (argv[3]) == SQLITE_INTEGER)
756 {
757 int_value = sqlite3_value_int (argv[3]);
758 m = int_value;
759 }
760 else
761 {
762 sqlite3_result_null (context);
763 return;
764 }
765
766 gpkgMakePointZM (x, y, z, m,
767 GEOPACKAGE_DEFAULT_UNDEFINED_SRID, &p_result, &len);
768 if (!p_result)
769 {
770 sqlite3_result_null (context);
771 }
772 else
773 {
774 sqlite3_result_blob (context, p_result, len, free);
775 }
776 }
777
778 GEOPACKAGE_PRIVATE void
fnct_gpkgMakePointZMWithSRID(sqlite3_context * context,int argc UNUSED,sqlite3_value ** argv)779 fnct_gpkgMakePointZMWithSRID (sqlite3_context * context, int argc UNUSED,
780 sqlite3_value ** argv)
781 {
782 /* SQL function:
783 / gpkgMakePointZM(x, y, z, m, srid)
784 /
785 / Creates a GeoPackage geometry POINT ZM
786 /
787 / returns nothing on success, raises exception on error
788 */
789 unsigned int len;
790 int int_value;
791 unsigned char *p_result = NULL;
792 double x;
793 double y;
794 double z;
795 double m;
796 int srid;
797 GEOPACKAGE_UNUSED (); /* LCOV_EXCL_LINE */
798 if (sqlite3_value_type (argv[0]) == SQLITE_FLOAT)
799 {
800 x = sqlite3_value_double (argv[0]);
801 }
802 else if (sqlite3_value_type (argv[0]) == SQLITE_INTEGER)
803 {
804 int_value = sqlite3_value_int (argv[0]);
805 x = int_value;
806 }
807 else
808 {
809 sqlite3_result_null (context);
810 return;
811 }
812 if (sqlite3_value_type (argv[1]) == SQLITE_FLOAT)
813 {
814 y = sqlite3_value_double (argv[1]);
815 }
816 else if (sqlite3_value_type (argv[1]) == SQLITE_INTEGER)
817 {
818 int_value = sqlite3_value_int (argv[1]);
819 y = int_value;
820 }
821 else
822 {
823 sqlite3_result_null (context);
824 return;
825 }
826 if (sqlite3_value_type (argv[2]) == SQLITE_FLOAT)
827 {
828 z = sqlite3_value_double (argv[2]);
829 }
830 else if (sqlite3_value_type (argv[2]) == SQLITE_INTEGER)
831 {
832 int_value = sqlite3_value_int (argv[2]);
833 z = int_value;
834 }
835 else
836 {
837 sqlite3_result_null (context);
838 return;
839 }
840 if (sqlite3_value_type (argv[3]) == SQLITE_FLOAT)
841 {
842 m = sqlite3_value_double (argv[3]);
843 }
844 else if (sqlite3_value_type (argv[3]) == SQLITE_INTEGER)
845 {
846 int_value = sqlite3_value_int (argv[3]);
847 m = int_value;
848 }
849 else
850 {
851 sqlite3_result_null (context);
852 return;
853 }
854 if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
855 {
856 sqlite3_result_null (context);
857 return;
858 }
859 srid = sqlite3_value_int (argv[4]);
860
861 gpkgMakePointZM (x, y, z, m, srid, &p_result, &len);
862 if (!p_result)
863 {
864 sqlite3_result_null (context);
865 }
866 else
867 {
868 sqlite3_result_blob (context, p_result, len, free);
869 }
870 }
871 #endif
872