diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2017-01-24 02:29:04 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2017-01-24 02:29:04 +0400 |
commit | 0d107a85b3dd6969e66cc9cb4bd29e1cc92a7d18 (patch) | |
tree | 4ea2e72a0886dae95c31ecdc9556b381c4e097d5 /sql/item_geofunc.cc | |
parent | 1f3ad6a4ba63074c51c84dff449c35a8314a7f36 (diff) | |
download | mariadb-git-0d107a85b3dd6969e66cc9cb4bd29e1cc92a7d18.tar.gz |
MDEV-11042 Implement GeoJSON functions.
ST_AsGeoJSON and ST_GeomFromGeoJSON functions implemented.
Diffstat (limited to 'sql/item_geofunc.cc')
-rw-r--r-- | sql/item_geofunc.cc | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index c856aa985b3..7ac2e054e8c 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -121,6 +121,65 @@ String *Item_func_geometry_from_wkb::val_str(String *str) } +void report_json_error_ex(String *js, json_engine_t *je, + const char *fname, int n_param, + Sql_condition::enum_warning_level lv); + +String *Item_func_geometry_from_json::val_str(String *str) +{ + DBUG_ASSERT(fixed == 1); + Geometry_buffer buffer; + String *js= args[0]->val_str_ascii(&tmp_js); + uint32 srid= 0; + json_engine_t je; + + if ((null_value= args[0]->null_value)) + return 0; + + if ((arg_count == 2) && !args[1]->null_value) + srid= (uint32)args[1]->val_int(); + + str->set_charset(&my_charset_bin); + if (str->reserve(SRID_SIZE, 512)) + return 0; + str->length(0); + str->q_append(srid); + + json_scan_start(&je, js->charset(), (const uchar *) js->ptr(), + (const uchar *) js->end()); + + if ((null_value= !Geometry::create_from_json(&buffer, &je, str))) + { + int code= 0; + + switch (je.s.error) + { + case Geometry::GEOJ_INCORRECT_GEOJSON: + code= ER_GEOJSON_INCORRECT; + break; + case Geometry::GEOJ_TOO_FEW_POINTS: + code= ER_GEOJSON_TOO_FEW_POINTS; + break; + case Geometry::GEOJ_POLYGON_NOT_CLOSED: + code= ER_GEOJSON_NOT_CLOSED; + break; + default: + report_json_error_ex(js, &je, func_name(), 0, Sql_condition::WARN_LEVEL_WARN); + return NULL; + } + + if (code) + { + THD *thd= current_thd; + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, code, + ER_THD(thd, code)); + } + return 0; + } + return str; +} + + String *Item_func_as_wkt::val_str_ascii(String *str) { DBUG_ASSERT(fixed == 1); @@ -170,6 +229,37 @@ String *Item_func_as_wkb::val_str(String *str) } +void Item_func_as_geojson::fix_length_and_dec() +{ + collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); + max_length=MAX_BLOB_WIDTH; + maybe_null= 1; +} + + +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); + Geometry_buffer buffer; + Geometry *geom= NULL; + const char *dummy; + + if ((null_value= + (args[0]->null_value || + !(geom= Geometry::construct(&buffer, swkb->ptr(), swkb->length()))))) + return 0; + + str->length(0); + str->set_charset(&my_charset_latin1); + if ((null_value= geom->as_json(str, FLOATING_POINT_DECIMALS, &dummy))) + return 0; + + return str; +} + + String *Item_func_geometry_type::val_str_ascii(String *str) { DBUG_ASSERT(fixed == 1); |