Commit 4ff6ebf7 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-12181 ST_AsGeoJSON argument does not limit decimals.

        Options handling implemented for ST_AsGeoJSON.
parent c508691a
......@@ -74,6 +74,21 @@ POINT(5.3 15)
SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',4));
ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',4))
POINT(5.3 15)
SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),2);
ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),2)
{"type": "Point", "coordinates": [5.36, 7.27]}
SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),1);
ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),1)
{"type": "Point", "coordinates": [5.4, 7.3]}
SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),10);
ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),10)
{"type": "Point", "coordinates": [5.363, 7.266]}
SELECT ST_AsGeoJSON(ST_GeomFromText("POINT(10 11)"), 100, 1);
ST_AsGeoJSON(ST_GeomFromText("POINT(10 11)"), 100, 1)
{"bbox": [10, 11, 10, 11], "type": "Point", "coordinates": [10, 11]}
SELECT ST_AsGeoJSON(ST_GeomFromText("POINT(10 11)"), 100, 5);
ST_AsGeoJSON(ST_GeomFromText("POINT(10 11)"), 100, 5)
{"bbox": [10, 11, 10, 11], "type": "Point", "coordinates": [10, 11]}
#
# End of 10.2 tests
#
......@@ -33,6 +33,13 @@ SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.
SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',3));
SELECT ST_AsText(ST_GeomFromGeoJSON('{ "type": "Point", "coordinates": [5.3, 15.0, 4.3]}',4));
SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),2);
SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),1);
SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.363 7.266)'),10);
SELECT ST_AsGeoJSON(ST_GeomFromText("POINT(10 11)"), 100, 1);
SELECT ST_AsGeoJSON(ST_GeomFromText("POINT(10 11)"), 100, 5);
--echo #
--echo # End of 10.2 tests
--echo #
......@@ -259,6 +259,8 @@ String *Item_func_as_geojson::val_str_ascii(String *str)
DBUG_ASSERT(fixed == 1);
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
uint max_dec= FLOATING_POINT_DECIMALS;
longlong options= 0;
Geometry_buffer buffer;
Geometry *geom= NULL;
const char *dummy;
......@@ -268,12 +270,41 @@ String *Item_func_as_geojson::val_str_ascii(String *str)
!(geom= Geometry::construct(&buffer, swkb->ptr(), swkb->length())))))
return 0;
if (arg_count > 1)
{
max_dec= (uint) args[1]->val_int();
if (args[1]->null_value)
max_dec= FLOATING_POINT_DECIMALS;
if (arg_count > 2)
{
options= args[2]->val_int();
if (args[2]->null_value)
options= 0;
}
}
str->length(0);
str->set_charset(&my_charset_latin1);
if ((null_value= geom->as_json(str, FLOATING_POINT_DECIMALS, &dummy)))
if (str->reserve(1, 512))
return 0;
str->qs_append('{');
if (options & 1)
{
if (geom->bbox_as_json(str) || str->append(", ", 2))
goto error;
}
if ((geom->as_json(str, max_dec, &dummy) || str->append("}", 1)))
goto error;
return str;
error:
null_value= 1;
return 0;
}
......
......@@ -21,6 +21,10 @@
#include "gstream.h" // Gis_read_stream
#include "sql_string.h" // String
/* This is from item_func.h. Didn't want to #include the whole file. */
double my_double_round(double value, longlong dec, bool dec_unsigned,
bool truncate);
#ifdef HAVE_SPATIAL
/*
......@@ -250,6 +254,8 @@ static const uchar feature_type[]= "feature";
static const int feature_type_len= 7;
static const uchar feature_coll_type[]= "featurecollection";
static const int feature_coll_type_len= 17;
static const uchar bbox_keyname[]= "bbox";
static const int bbox_keyname_len= 4;
int Geometry::as_json(String *wkt, uint max_dec_digits, const char **end)
......@@ -258,7 +264,7 @@ int Geometry::as_json(String *wkt, uint max_dec_digits, const char **end)
if (wkt->reserve(4 + type_keyname_len + 2 + len + 2 + 2 +
coord_keyname_len + 4, 512))
return 1;
wkt->qs_append("{\"", 2);
wkt->qs_append("\"", 1);
wkt->qs_append((const char *) type_keyname, type_keyname_len);
wkt->qs_append("\": \"", 4);
wkt->qs_append(get_class_info()->m_geojson_name.str, len);
......@@ -269,10 +275,35 @@ int Geometry::as_json(String *wkt, uint max_dec_digits, const char **end)
wkt->qs_append((const char *) coord_keyname, coord_keyname_len);
wkt->qs_append("\": ", 3);
if (get_data_as_json(wkt, max_dec_digits, end) ||
wkt->reserve(1))
if (get_data_as_json(wkt, max_dec_digits, end))
return 1;
wkt->qs_append('}');
return 0;
}
int Geometry::bbox_as_json(String *wkt)
{
MBR mbr;
const char *end;
if (wkt->reserve(5 + bbox_keyname_len + (FLOATING_POINT_DECIMALS+2)*4, 512))
return 1;
wkt->qs_append("\"", 1);
wkt->qs_append((const char *) bbox_keyname, bbox_keyname_len);
wkt->qs_append("\": [", 4);
if (get_mbr(&mbr, &end))
return 1;
wkt->qs_append(mbr.xmin);
wkt->qs_append(", ", 2);
wkt->qs_append(mbr.ymin);
wkt->qs_append(", ", 2);
wkt->qs_append(mbr.xmax);
wkt->qs_append(", ", 2);
wkt->qs_append(mbr.ymax);
wkt->qs_append("]", 1);
return 0;
}
......@@ -670,6 +701,11 @@ static void append_json_point(String *txt, uint max_dec, const char *data)
{
double x,y;
get_point(&x, &y, data);
if (max_dec < FLOATING_POINT_DECIMALS)
{
x= my_double_round(x, max_dec, FALSE, FALSE);
y= my_double_round(y, max_dec, FALSE, FALSE);
}
txt->qs_append('[');
txt->qs_append(x);
txt->qs_append(", ", 2);
......@@ -3106,12 +3142,14 @@ bool Gis_geometry_collection::get_data_as_json(String *txt, uint max_dec_digits,
if (!(geom= create_by_typeid(&buffer, wkb_type)))
return 1;
geom->set_data_ptr(data, (uint) (m_data_end - data));
if (geom->as_json(txt, max_dec_digits, &data) ||
txt->append(STRING_WITH_LEN(", "), 512))
if (txt->append("{", 1) ||
geom->as_json(txt, max_dec_digits, &data) ||
txt->append(STRING_WITH_LEN("}, "), 512))
return 1;
}
txt->length(txt->length() - 2);
txt->qs_append(']');
if (txt->append("]", 1))
return 1;
*end= data;
return 0;
......
......@@ -323,6 +323,7 @@ class Geometry
String *res, Gcalc_result_receiver &rr);
int as_wkt(String *wkt, const char **end);
int as_json(String *wkt, uint max_dec_digits, const char **end);
int bbox_as_json(String *wkt);
inline void set_data_ptr(const char *data, uint32 data_len)
{
......
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