1 /********************************************************************** 2 * 3 * PostGIS - Spatial Types for PostgreSQL 4 * http://postgis.net 5 * 6 * PostGIS is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * PostGIS is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with PostGIS. If not, see <http://www.gnu.org/licenses/>. 18 * 19 ********************************************************************** 20 * 21 * Copyright 2013 Nicklas Avén 22 * 23 **********************************************************************/ 24 25 26 /********************************************************************** 27 * 28 * PostGIS - Spatial Types for PostgreSQL 29 * http://postgis.net 30 * Copyright 2013 Nicklas Avén 31 * 32 * This is free software; you can redistribute and/or modify it under 33 * the terms of the GNU General Public Licence. See the COPYING file. 34 * 35 **********************************************************************/ 36 37 #include "liblwgeom_internal.h" 38 #include "lwgeom_log.h" 39 #include <limits.h> 40 #include "bytebuffer.h" 41 42 /* Maximum number of geometry dimmensions that internal arrays can hold */ 43 #define MAX_N_DIMS 4 44 45 #define MAX_BBOX_SIZE 64 46 #define MAX_SIZE_SIZE 8 47 48 49 /** 50 * Header true/false flags 51 */ 52 53 #define FIRST_BYTE_SET_BBOXES(flag, bool) ((flag) = ((bool) ? (flag) | 0x01 : (flag) & (~0x01))) 54 #define FIRST_BYTE_SET_SIZES(flag, bool) ((flag) = ((bool) ? (flag) | 0x02 : (flag) & (~0x02))) 55 #define FIRST_BYTE_SET_IDLIST(flag, bool) ((flag) = ((bool) ? (flag) | 0x04 : (flag) & (~0x04))) 56 #define FIRST_BYTE_SET_EXTENDED(flag, bool) ((flag) = ((bool) ? (flag) | 0x08 : (flag) & (~0x08))) 57 #define FIRST_BYTE_SET_EMPTY(flag, bool) ((flag) = ((bool) ? (flag) | 0x10 : (flag) & (~0x10))) 58 59 60 /** 61 * Macros for manipulating the 'type_precision' int. An int8_t used as follows: 62 * Type 4 bits 63 * Precision 4 bits 64 */ 65 66 #define TYPE_PREC_SET_TYPE(flag, type) ((flag) = ((flag) & 0xF0) | (((type) & 0x0F))) 67 #define TYPE_PREC_SET_PREC(flag, prec) ((flag) = ((flag) & 0x0F) | (((prec) & 0x0F) << 4)) 68 69 #define HIGHER_DIM_SET_HASZ(flag, bool) ((flag) = ((bool) ? (flag) | 0x01 : (flag) & (~0x01))) 70 #define HIGHER_DIM_SET_HASM(flag, bool) ((flag) = ((bool) ? (flag) | 0x02 : (flag) & (~0x02))) 71 72 #define HIGHER_DIM_SET_PRECZ(flag, prec) ((flag) = ((flag) & 0xE3) | (((prec) & 0x07) << 2)) 73 #define HIGHER_DIM_SET_PRECM(flag, prec) ((flag) = ((flag) & 0x1F) | (((prec) & 0x07) << 5)) 74 75 typedef struct 76 { 77 /* Options defined at start */ 78 uint8_t variant; 79 int8_t prec_xy; 80 int8_t prec_z; 81 int8_t prec_m; 82 float factor[4]; /*What factor to multiply the coordiinates with to get the requested precision*/ 83 } TWKB_GLOBALS; 84 85 typedef struct 86 { 87 uint8_t variant; /*options that change at runtime*/ 88 bytebuffer_t *header_buf; 89 bytebuffer_t *geom_buf; 90 int hasz; 91 int hasm; 92 const int64_t *idlist; 93 int64_t bbox_min[MAX_N_DIMS]; 94 int64_t bbox_max[MAX_N_DIMS]; 95 int64_t accum_rels[MAX_N_DIMS]; /*Holds the acculmulated relative values*/ 96 } TWKB_STATE; 97 98 static int lwgeom_to_twkb_buf(const LWGEOM *geom, TWKB_GLOBALS *global_values, TWKB_STATE *ts); 99 100 static int lwpoint_to_twkb_buf(const LWPOINT *line, TWKB_GLOBALS *global_values, TWKB_STATE *ts); 101 static int lwline_to_twkb_buf(const LWLINE *line, TWKB_GLOBALS *global_values, TWKB_STATE *ts); 102 static int lwpoly_to_twkb_buf(const LWPOLY *poly, TWKB_GLOBALS *global_values, TWKB_STATE *ts); 103 static int lwcollection_to_twkb_buf(const LWCOLLECTION *col, TWKB_GLOBALS *global_values, TWKB_STATE *ts); 104 static int lwgeom_write_to_buffer(const LWGEOM *geom, TWKB_GLOBALS *global_values, TWKB_STATE *parent_state); 105 106