diff options
Diffstat (limited to 'sql/spatial.cc')
-rw-r--r-- | sql/spatial.cc | 99 |
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; |