summaryrefslogtreecommitdiff
path: root/sql/spatial.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/spatial.cc')
-rw-r--r--sql/spatial.cc99
1 files changed, 73 insertions, 26 deletions
diff --git a/sql/spatial.cc b/sql/spatial.cc
index 7c9d8bb771e..1ba754b6b13 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -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;
+
+ 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('}');
+
+ 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;
}
@@ -339,7 +370,7 @@ Geometry *Geometry::create_from_wkb(Geometry_buffer *buffer,
Geometry *Geometry::create_from_json(Geometry_buffer *buffer,
- json_engine_t *je, String *res)
+ json_engine_t *je, bool er_on_3D, String *res)
{
Class_info *ci= NULL;
const uchar *coord_start= NULL, *geom_start= NULL,
@@ -514,14 +545,14 @@ create_geom:
result= (*ci->m_create_func)(buffer->data);
res->q_append((char) wkb_ndr);
res->q_append((uint32) result->get_class_info()->m_type_id);
- if (result->init_from_json(je, res))
+ if (result->init_from_json(je, er_on_3D, res))
goto err_return;
return result;
handle_geometry_key:
json_scan_start(je, je->s.cs, geometry_start, je->s.str_end);
- return create_from_json(buffer, je, res);
+ return create_from_json(buffer, je, er_on_3D, res);
err_return:
return NULL;
@@ -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);
@@ -780,7 +816,8 @@ uint Gis_point::init_from_wkb(const char *wkb, uint len,
}
-static int read_point_from_json(json_engine_t *je, double *x, double *y)
+static int read_point_from_json(json_engine_t *je, bool er_on_3D,
+ double *x, double *y)
{
int n_coord= 0, err;
double tmp, *d;
@@ -803,14 +840,17 @@ static int read_point_from_json(json_engine_t *je, double *x, double *y)
n_coord++;
}
- return 0;
+ if (n_coord <= 2 || !er_on_3D)
+ return 0;
+ je->s.error= Geometry::GEOJ_DIMENSION_NOT_SUPPORTED;
+ return 1;
bad_coordinates:
je->s.error= Geometry::GEOJ_INCORRECT_GEOJSON;
return 1;
}
-bool Gis_point::init_from_json(json_engine_t *je, String *wkb)
+bool Gis_point::init_from_json(json_engine_t *je, bool er_on_3D, String *wkb)
{
double x, y;
if (json_read_value(je))
@@ -822,7 +862,7 @@ bool Gis_point::init_from_json(json_engine_t *je, String *wkb)
return TRUE;
}
- if (read_point_from_json(je, &x, &y) ||
+ if (read_point_from_json(je, er_on_3D, &x, &y) ||
wkb->reserve(POINT_DATA_SIZE))
return TRUE;
@@ -971,7 +1011,8 @@ uint Gis_line_string::init_from_wkb(const char *wkb, uint len,
}
-bool Gis_line_string::init_from_json(json_engine_t *je, String *wkb)
+bool Gis_line_string::init_from_json(json_engine_t *je, bool er_on_3D,
+ String *wkb)
{
uint32 n_points= 0;
uint32 np_pos= wkb->length();
@@ -994,7 +1035,7 @@ bool Gis_line_string::init_from_json(json_engine_t *je, String *wkb)
{
DBUG_ASSERT(je->state == JST_VALUE);
- if (p.init_from_json(je, wkb))
+ if (p.init_from_json(je, er_on_3D, wkb))
return TRUE;
n_points++;
}
@@ -1364,7 +1405,7 @@ uint Gis_polygon::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,
}
-bool Gis_polygon::init_from_json(json_engine_t *je, String *wkb)
+bool Gis_polygon::init_from_json(json_engine_t *je, bool er_on_3D, String *wkb)
{
uint32 n_linear_rings= 0;
uint32 lr_pos= wkb->length();
@@ -1389,7 +1430,7 @@ bool Gis_polygon::init_from_json(json_engine_t *je, String *wkb)
DBUG_ASSERT(je->state == JST_VALUE);
uint32 ls_pos=wkb->length();
- if (ls.init_from_json(je, wkb))
+ if (ls.init_from_json(je, er_on_3D, wkb))
return TRUE;
ls.set_data_ptr(wkb->ptr() + ls_pos, wkb->length() - ls_pos);
if (ls.is_closed(&closed) || !closed)
@@ -1855,7 +1896,8 @@ uint Gis_multi_point::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,
}
-bool Gis_multi_point::init_from_json(json_engine_t *je, String *wkb)
+bool Gis_multi_point::init_from_json(json_engine_t *je, bool er_on_3D,
+ String *wkb)
{
uint32 n_points= 0;
uint32 np_pos= wkb->length();
@@ -1883,7 +1925,7 @@ bool Gis_multi_point::init_from_json(json_engine_t *je, String *wkb)
wkb->q_append((char) wkb_ndr);
wkb->q_append((uint32) wkb_point);
- if (p.init_from_json(je, wkb))
+ if (p.init_from_json(je, er_on_3D, wkb))
return TRUE;
n_points++;
}
@@ -2123,7 +2165,8 @@ uint Gis_multi_line_string::init_from_wkb(const char *wkb, uint len,
}
-bool Gis_multi_line_string::init_from_json(json_engine_t *je, String *wkb)
+bool Gis_multi_line_string::init_from_json(json_engine_t *je, bool er_on_3D,
+ String *wkb)
{
uint32 n_line_strings= 0;
uint32 ls_pos= wkb->length();
@@ -2151,7 +2194,7 @@ bool Gis_multi_line_string::init_from_json(json_engine_t *je, String *wkb)
wkb->q_append((char) wkb_ndr);
wkb->q_append((uint32) wkb_linestring);
- if (ls.init_from_json(je, wkb))
+ if (ls.init_from_json(je, er_on_3D, wkb))
return TRUE;
n_line_strings++;
@@ -2511,7 +2554,8 @@ uint Gis_multi_polygon::init_from_opresult(String *bin,
}
-bool Gis_multi_polygon::init_from_json(json_engine_t *je, String *wkb)
+bool Gis_multi_polygon::init_from_json(json_engine_t *je, bool er_on_3D,
+ String *wkb)
{
uint32 n_polygons= 0;
int np_pos= wkb->length();
@@ -2539,7 +2583,7 @@ bool Gis_multi_polygon::init_from_json(json_engine_t *je, String *wkb)
wkb->q_append((char) wkb_ndr);
wkb->q_append((uint32) wkb_polygon);
- if (p.init_from_json(je, wkb))
+ if (p.init_from_json(je, er_on_3D, wkb))
return TRUE;
n_polygons++;
@@ -2986,7 +3030,8 @@ uint Gis_geometry_collection::init_from_wkb(const char *wkb, uint len,
}
-bool Gis_geometry_collection::init_from_json(json_engine_t *je, String *wkb)
+bool Gis_geometry_collection::init_from_json(json_engine_t *je, bool er_on_3D,
+ String *wkb)
{
uint32 n_objects= 0;
uint32 no_pos= wkb->length();
@@ -3012,7 +3057,7 @@ bool Gis_geometry_collection::init_from_json(json_engine_t *je, String *wkb)
DBUG_ASSERT(je->state == JST_VALUE);
- if (!(g= create_from_json(&buffer, je, wkb)))
+ if (!(g= create_from_json(&buffer, je, er_on_3D, wkb)))
return TRUE;
*je= sav_je;
@@ -3097,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;