Commit b998fe34 authored by Darafei Praliaskouski's avatar Darafei Praliaskouski

Encoded Polyline of EMPTY

Pull in from trunk Closes #3982 git-svn-id: http://svn.osgeo.org/postgis/branches/2.4@16264 b70326c6-7e19-0410-871a-916f4a2858ee
parent a90150e1
Pipeline #16075660 passed with stage
in 16 minutes 36 seconds
......@@ -9,6 +9,9 @@ PostGIS 2.4.3
- #3965, ST_ClusterKMeans used to lose some clusters on initialization
(Darafei Praliaskouski)
- #3956, Brin opclass object does not upgrade properly (Sandro Santilli)
- #3982, ST_AsEncodedPolyline supports LINESTRING EMPTY and MULTIPOINT EMPTY
(Darafei Praliaskouski)
* Enhancements *
- #3944, Update to EPSG register v9.2 (Even Rouault)
......
/**********************************************************************
*
* PostGIS - Spatial Types for PostgreSQL
* http://postgis.net
*
* Copyright 2014 Kashif Rasul <kashif.rasul@gmail.com> and
* Shoaib Burq <saburq@gmail.com>
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU General Public Licence. See the COPYING file.
*
**********************************************************************/
*
* PostGIS - Spatial Types for PostgreSQL
* http://postgis.net
*
* Copyright 2014 Kashif Rasul <kashif.rasul@gmail.com> and
* Shoaib Burq <saburq@gmail.com>
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU General Public Licence. See the COPYING file.
*
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
......@@ -19,10 +19,11 @@
#include "liblwgeom_internal.h"
#include "cu_tester.h"
static void do_encoded_polyline_test(char * in, int precision, char * out)
static void
do_encoded_polyline_test(char* in, int precision, char* out)
{
LWGEOM *g;
char * h;
LWGEOM* g;
char* h;
g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE);
h = lwgeom_to_encoded_polyline(g, precision);
......@@ -36,66 +37,65 @@ static void do_encoded_polyline_test(char * in, int precision, char * out)
lwfree(h);
}
static void out_encoded_polyline_test_geoms(void)
static void
out_encoded_polyline_test_geoms(void)
{
/* Magic Linestring */
do_encoded_polyline_test(
"SRID=4326;LINESTRING(33.6729 38.7071,33.6692 38.701,33.6673 38.6972,33.6626 38.6871)",
5,
"k~fkFsvolEbe@bVvVzJb~@j\\");
return;
"SRID=4326;LINESTRING(33.6729 38.7071,33.6692 38.701,"
"33.6673 38.6972,33.6626 38.6871)",
5,
"k~fkFsvolEbe@bVvVzJb~@j\\");
/* Linestring */
do_encoded_polyline_test(
"LINESTRING(-120.2 38.5,-120.95 40.7,-126.453 43.252)",
5,
"_p~iF~ps|U_ulLnnqC_mqNvxq`@");
"LINESTRING(-120.2 38.5,-120.95 40.7,-126.453 43.252)",
5,
"_p~iF~ps|U_ulLnnqC_mqNvxq`@");
do_encoded_polyline_test("LINESTRING EMPTY", 5, "");
/* MultiPoint */
do_encoded_polyline_test(
"MULTIPOINT(-120.2 38.5,-120.95 40.7)",
5,
"_p~iF~ps|U_ulLnnqC");
"MULTIPOINT(-120.2 38.5,-120.95 40.7)", 5, "_p~iF~ps|U_ulLnnqC");
do_encoded_polyline_test("MULTIPOINT EMPTY", 5, "");
}
static void out_encoded_polyline_test_srid(void)
static void
out_encoded_polyline_test_srid(void)
{
/* SRID - with PointArray */
do_encoded_polyline_test(
"SRID=4326;LINESTRING(0 1,2 3)",
5,
"_ibE?_seK_seK");
"SRID=4326;LINESTRING(0 1,2 3)", 5, "_ibE?_seK_seK");
/* wrong SRID */
do_encoded_polyline_test(
"SRID=4327;LINESTRING(0 1,2 3)",
5,
"_ibE?_seK_seK");
"SRID=4327;LINESTRING(0 1,2 3)", 5, "_ibE?_seK_seK");
}
static void out_encoded_polyline_test_precision(void)
static void
out_encoded_polyline_test_precision(void)
{
/* Linestring */
do_encoded_polyline_test(
"LINESTRING(-0.250691 49.283048,-0.250633 49.283376,-0.250502 49.283972,-0.251245 49.284028,-0.251938 49.284232,-0.251938 49.2842)",
6,
"o}~~|AdshNoSsBgd@eGoBlm@wKhj@~@?");
"LINESTRING(-0.250691 49.283048, -0.250633 49.283376,"
"-0.250502 49.283972, -0.251245 49.284028, -0.251938 "
"49.284232, -0.251938 49.2842)",
6,
"o}~~|AdshNoSsBgd@eGoBlm@wKhj@~@?");
/* MultiPoint */
do_encoded_polyline_test(
"MULTIPOINT(-120.2 38.5,-120.95 40.7)",
3,
"gejAnwiFohCzm@");
"MULTIPOINT(-120.2 38.5,-120.95 40.7)", 3, "gejAnwiFohCzm@");
}
/*
** Used by test harness to register the tests in this file.
*/
void out_encoded_polyline_suite_setup(void);
void out_encoded_polyline_suite_setup(void)
void
out_encoded_polyline_suite_setup(void)
{
CU_pSuite suite = CU_add_suite("encoded_polyline_output", NULL, NULL);
PG_ADD_TEST(suite, out_encoded_polyline_test_geoms);
......
......@@ -18,21 +18,21 @@
*
**********************************************************************
*
* Copyright 2014 Kashif Rasul <kashif.rasul@gmail.com> and
* Copyright 2014 Kashif Rasul <kashif.rasul@gmail.com> and
* Shoaib Burq <saburq@gmail.com>
*
**********************************************************************/
#include "stringbuffer.h"
#include "liblwgeom_internal.h"
static char * lwline_to_encoded_polyline(const LWLINE*, int precision);
static char * lwmmpoint_to_encoded_polyline(const LWMPOINT*, int precision);
static char * pointarray_to_encoded_polyline(const POINTARRAY*, int precision);
static char* lwline_to_encoded_polyline(const LWLINE*, int precision);
static char* lwmmpoint_to_encoded_polyline(const LWMPOINT*, int precision);
static char* pointarray_to_encoded_polyline(const POINTARRAY*, int precision);
/* takes a GEOMETRY and returns an Encoded Polyline representation */
extern char *
lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision)
extern char*
lwgeom_to_encoded_polyline(const LWGEOM* geom, int precision)
{
int type = geom->type;
switch (type)
......@@ -42,53 +42,66 @@ lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision)
case MULTIPOINTTYPE:
return lwmmpoint_to_encoded_polyline((LWMPOINT*)geom, precision);
default:
lwerror("lwgeom_to_encoded_polyline: '%s' geometry type not supported", lwtype_name(type));
lwerror("lwgeom_to_encoded_polyline: '%s' geometry type not supported",
lwtype_name(type));
return NULL;
}
}
static
char * lwline_to_encoded_polyline(const LWLINE *line, int precision)
static char*
lwline_to_encoded_polyline(const LWLINE* line, int precision)
{
return pointarray_to_encoded_polyline(line->points, precision);
}
static
char * lwmmpoint_to_encoded_polyline(const LWMPOINT *mpoint, int precision)
static char*
lwmmpoint_to_encoded_polyline(const LWMPOINT* mpoint, int precision)
{
LWLINE *line = lwline_from_lwmpoint(mpoint->srid, mpoint);
char *encoded_polyline = lwline_to_encoded_polyline(line, precision);
LWLINE* line = lwline_from_lwmpoint(mpoint->srid, mpoint);
char* encoded_polyline = lwline_to_encoded_polyline(line, precision);
lwline_free(line);
return encoded_polyline;
}
static
char * pointarray_to_encoded_polyline(const POINTARRAY *pa, int precision)
static char*
pointarray_to_encoded_polyline(const POINTARRAY* pa, int precision)
{
int i;
const POINT2D *prevPoint;
int *delta = lwalloc(2*sizeof(int)*pa->npoints);
char *encoded_polyline = NULL;
stringbuffer_t *sb;
double scale = pow(10,precision);
const POINT2D* prevPoint;
int* delta;
char* encoded_polyline = NULL;
stringbuffer_t* sb;
double scale = pow(10, precision);
/* Empty input is empty string */
if (pa->npoints == 0) {
encoded_polyline = lwalloc(1 * sizeof(char));
encoded_polyline[0] = 0;
return encoded_polyline;
}
delta = lwalloc(2 * sizeof(int) * pa->npoints);
/* Take the double value and multiply it by 1x10^precision, rounding the result */
/* Take the double value and multiply it by 1x10^precision, rounding the
* result */
prevPoint = getPoint2d_cp(pa, 0);
delta[0] = round(prevPoint->y*scale);
delta[1] = round(prevPoint->x*scale);
delta[0] = round(prevPoint->y * scale);
delta[1] = round(prevPoint->x * scale);
/* points only include the offset from the previous point */
for (i=1; i<pa->npoints; i++)
/* Points only include the offset from the previous point */
for (i = 1; i < pa->npoints; i++)
{
const POINT2D *point = getPoint2d_cp(pa, i);
delta[2*i] = round(point->y*scale) - round(prevPoint->y*scale);
delta[(2*i)+1] = round(point->x*scale) - round(prevPoint->x*scale);
const POINT2D* point = getPoint2d_cp(pa, i);
delta[2 * i] = round(point->y * scale) - round(prevPoint->y * scale);
delta[(2 * i) + 1] =
round(point->x * scale) - round(prevPoint->x * scale);
prevPoint = point;
}
/* value to binary: a negative value must be calculated using its two's complement */
for (i=0; i<pa->npoints*2; i++)
/* value to binary: a negative value must be calculated using its two's
* complement */
for (i = 0; i < pa->npoints * 2; i++)
{
/* Multiply by 2 for a signed left shift */
delta[i] *= 2;
......@@ -99,11 +112,12 @@ char * pointarray_to_encoded_polyline(const POINTARRAY *pa, int precision)
}
sb = stringbuffer_create();
for (i=0; i<pa->npoints*2; i++)
for (i = 0; i < pa->npoints * 2; i++)
{
int numberToEncode = delta[i];
while (numberToEncode >= 0x20) {
while (numberToEncode >= 0x20)
{
/* Place the 5-bit chunks into reverse order or
each value with 0x20 if another bit chunk follows and add 63*/
int nextValue = (0x20 | (numberToEncode & 0x1f)) + 63;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment