PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
lwout_encoded_polyline.c
Go to the documentation of this file.
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 2014 Kashif Rasul <kashif.rasul@gmail.com> and
22 * Shoaib Burq <saburq@gmail.com>
23 *
24 **********************************************************************/
25
26#include "stringbuffer.h"
27#include "liblwgeom_internal.h"
28
29static char* lwline_to_encoded_polyline(const LWLINE*, int precision);
30static char* lwmmpoint_to_encoded_polyline(const LWMPOINT*, int precision);
32
33/* takes a GEOMETRY and returns an Encoded Polyline representation */
34extern char*
36{
37 int type = geom->type;
38 switch (type)
39 {
40 case LINETYPE:
42 case MULTIPOINTTYPE:
44 default:
45 lwerror("lwgeom_to_encoded_polyline: '%s' geometry type not supported",
46 lwtype_name(type));
47 return NULL;
48 }
49}
50
51static char*
56
57static char*
59{
60 LWLINE* line = lwline_from_lwmpoint(mpoint->srid, mpoint);
61 char* encoded_polyline = lwline_to_encoded_polyline(line, precision);
62
63 lwline_free(line);
64 return encoded_polyline;
65}
66
67static char*
69{
70 uint32_t i;
71 const POINT2D* prevPoint;
72 int* delta;
73 char* encoded_polyline = NULL;
75 double scale = pow(10, precision);
76
77 /* Empty input is empty string */
78 if (pa->npoints == 0) {
79 encoded_polyline = lwalloc(1 * sizeof(char));
80 encoded_polyline[0] = 0;
81 return encoded_polyline;
82 }
83
84 delta = lwalloc(2 * sizeof(int) * pa->npoints);
85
86 /* Take the double value and multiply it by 1x10^precision, rounding the
87 * result */
88 prevPoint = getPoint2d_cp(pa, 0);
89 delta[0] = round(prevPoint->y * scale);
90 delta[1] = round(prevPoint->x * scale);
91
92 /* Points only include the offset from the previous point */
93 for (i = 1; i < pa->npoints; i++)
94 {
95 const POINT2D* point = getPoint2d_cp(pa, i);
96 delta[2 * i] = round(point->y * scale) - round(prevPoint->y * scale);
97 delta[(2 * i) + 1] =
98 round(point->x * scale) - round(prevPoint->x * scale);
99 prevPoint = point;
100 }
101
102 /* value to binary: a negative value must be calculated using its two's
103 * complement */
104 for (i = 0; i < pa->npoints * 2; i++)
105 {
106 /* Multiply by 2 for a signed left shift */
107 delta[i] *= 2;
108 /* if value is negative, invert this encoding */
109 if (delta[i] < 0) {
110 delta[i] = ~(delta[i]);
111 }
112 }
113
114 sb = stringbuffer_create();
115 for (i = 0; i < pa->npoints * 2; i++)
116 {
117 int numberToEncode = delta[i];
118
119 while (numberToEncode >= 0x20)
120 {
121 /* Place the 5-bit chunks into reverse order or
122 each value with 0x20 if another bit chunk follows and add 63*/
123 int nextValue = (0x20 | (numberToEncode & 0x1f)) + 63;
124 stringbuffer_aprintf(sb, "%c", (char)nextValue);
125
126 /* Break the binary value out into 5-bit chunks */
127 numberToEncode >>= 5;
128 }
129
130 numberToEncode += 63;
131 stringbuffer_aprintf(sb, "%c", (char)numberToEncode);
132 }
133
134 lwfree(delta);
135 encoded_polyline = stringbuffer_getstringcopy(sb);
137
138 return encoded_polyline;
139}
static uint8_t precision
Definition cu_in_twkb.c:25
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition lwutil.c:216
#define LINETYPE
Definition liblwgeom.h:117
#define MULTIPOINTTYPE
Definition liblwgeom.h:119
void * lwalloc(size_t size)
Definition lwutil.c:227
void lwfree(void *mem)
Definition lwutil.c:242
void lwline_free(LWLINE *line)
Definition lwline.c:67
LWLINE * lwline_from_lwmpoint(int32_t srid, const LWMPOINT *mpoint)
Definition lwline.c:275
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition lwutil.c:190
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition lwinline.h:91
static char * pointarray_to_encoded_polyline(const POINTARRAY *, int precision)
char * lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision)
static char * lwmmpoint_to_encoded_polyline(const LWMPOINT *, int precision)
static char * lwline_to_encoded_polyline(const LWLINE *, int precision)
stringbuffer_t * stringbuffer_create(void)
Allocate a new stringbuffer_t.
int stringbuffer_aprintf(stringbuffer_t *s, const char *fmt,...)
Appends a formatted string to the current string buffer, using the format and argument list provided.
char * stringbuffer_getstringcopy(stringbuffer_t *s)
Returns a newly allocated string large enough to contain the current state of the string.
void stringbuffer_destroy(stringbuffer_t *s)
Free the stringbuffer_t and all memory managed within it.
uint8_t type
Definition liblwgeom.h:448
POINTARRAY * points
Definition liblwgeom.h:469
int32_t srid
Definition liblwgeom.h:520
double y
Definition liblwgeom.h:376
double x
Definition liblwgeom.h:376
uint32_t npoints
Definition liblwgeom.h:413