From acde89d4889a788fa566ab5f96292f6ec6f55cc5 Mon Sep 17 00:00:00 2001 From: shw Date: Mon, 18 Sep 2023 03:12:52 +0000 Subject: [PATCH] support spatial data for protobuf --- include/lgraph/lgraph_spatial.h | 231 +++++++++++++++++++---------- include/lgraph/lgraph_types.h | 80 +++++----- src/core/data_type.h | 12 +- src/core/field_data_helper.h | 56 +++---- src/core/lgraph_spatial.cpp | 145 +++++++++--------- src/core/value.h | 38 ++--- src/http/http_server.cpp | 6 + src/protobuf/ha.proto | 6 + src/restful/server/rest_server.cpp | 9 ++ src/server/proto_convert.h | 26 +++- test/test_field_data_helper.cpp | 18 +-- test/test_lgraph_spatial.cpp | 188 +++++++++++------------ test/test_proto_convert.cpp | 12 ++ test/test_type_convert.cpp | 2 +- 14 files changed, 482 insertions(+), 347 deletions(-) diff --git a/include/lgraph/lgraph_spatial.h b/include/lgraph/lgraph_spatial.h index 40788989d4..1b7aa81e1f 100644 --- a/include/lgraph/lgraph_spatial.h +++ b/include/lgraph/lgraph_spatial.h @@ -15,7 +15,7 @@ * 1. 进一步通过测试样例检查ParseStringToValueOfFieldType与TryFieldDataToValueOfFieldType * 实现的正确性(空间数据与string数据的转换); * 2. FieldType2CType无法实现空间数据相关功能, 目前绕开实现。 - * 3. 确认line与polygon调用_SetVariableLengthValue实现正确。 + * 3. 确认line与Polygon调用_SetVariableLengthValue实现正确。 */ #pragma once @@ -48,14 +48,14 @@ typedef std::vector byte_vector; */ enum class SpatialType { NUL = 0, - POINT = 1, // point type, e.g. (1.0 2.0) - LINESTRING = 2, // linestring type, represent a linestring which is - // composed of different points. e.g (1.0 2.0, 3.0 2.0, 5.0 4.0) - POLYGON = 3 // polygon type, - // A polygon of Boost.Geometry is a polygon with or without holes + POINT = 1, // Point type, e.g. (1.0 2.0) + LINESTRING = 2, // LineString type, represent a LineString which is + // composed of different Points. e.g (1.0 2.0, 3.0 2.0, 5.0 4.0) + POLYGON = 3 // Polygon type, + // A Polygon of Boost.Geometry is a Polygon with or without holes // e.g (1.0 2.0, 3.0 2.0, 5.0 4.0, 1.0 2.0) for more detail, you can refer to // https://www.boost.org/doc/libs/1_68_0/libs/geometry/doc/html/geometry/ - // reference/concepts/concept_polygon.html + // reference/concepts/concept_Polygon.html }; /** @@ -73,44 +73,63 @@ enum class SRID { }; template -class point; +class Point; template -class linestring; +class LineString; template -class polygon; +class Polygon; -// true if little endian, false if big endian; +/** +* @brief return the given ewkb/wkb format data is little or big endian +* (determined by the first byte) +* +* @exception InputError Thrown if the input size is less than 42(the minimum +* wkb format length) +* +* @param EWKB expected wkb/ewkb format string; +* +* @returns true if little endian, false if big endian; +*/ bool Endian(const std::string& EWKB); /** * @brief transfer the given hex format string between little and big endian; -* the hex data is 4 bit each, so the size 2 hex data is 1 byte. We need -* to reverse every byte between the two endian. +* the hex data is 4 bit each, so every 2 hex data is 1 byte. We need +* to reverse each byte from the given input. +* +* @exception InputError Thrown if the input size is less than 42(the minimum +* wkb format length) * * @param [in,out] input little/big endian hex format string; */ void EndianTansfer(std::string& input); /** -* @brief transfer the srid_type into hex format(little endian); +* @brief transfer the srid_type(enum class) into hex format(little endian in default); * * @param srid_type Spatial Reference System Identifier; +* * @param width the length of hex format to transform; * -* @returns the hex format srid_type; +* @exception InputError Thrown if the input width is less than 4; +* +* @returns the hex format srid_type in little endian; */ std::string Srid2Hex(SRID srid_type, size_t width); /** * @brief transfer the wkb format data between big and little endian; * first, transfer the first byte. Then transfer the next 4 bytes, -* for linestring and polygon, we need to transfer extra bytes(which -* represents the number of points and rings). +* for LineString and Polygon, we need to transfer extra bytes(which +* represents the number of Points and rings). * then transfer the next n * 8 bytes. you can refer to the wkb layout * from the conments of TryDecodeWKB; -* +* +* @exception InputError Thrown if the input size is less than 42(the minimum +* wkb format length) +* * @param [in, out] WKB the wkb format data in big/little endian, out int little/big endian; */ void WkbEndianTransfer(std::string& WKB); @@ -119,10 +138,13 @@ void WkbEndianTransfer(std::string& WKB); * @brief transfer the EWKB format data from between big and little endian; * first, transfer the first byte. Then transfer the next 2 bytes(type) and * the following 2 bytes(dimension). Then transfer the next 4 bytes(srid). -* for linestring and polygon, we need to transfer extra bytes(which -* represents the number of points and rings). Then transfer the next n * 8 bytes. +* for LineString and Polygon, we need to transfer extra bytes(which +* represents the number of Points and rings). Then transfer the next n * 8 bytes. * you can refer to the EWKB layout from the comments of TryDecodeEWKB. * +* @exception InputError Thrown if the input size is less than 50(the minimum +* ewkb format length) +* * @param EWKB the EWKB format data in big/little endian; * * @returns the EWKB format data in little/big endian; @@ -130,15 +152,15 @@ void WkbEndianTransfer(std::string& WKB); std::string EwkbEndianTransfer(const std::string& EWKB); /** -* @brief set the wkb format string to EWKB format string; -* 关于EWKB与WKB layout 见TryDecodeEWKB与TryDecodeWKB注释; -* EWKB -> WKB 以little-endian为例: -* WKB[8] = 2; 在WKB[10]之后插入SRID信息, E6100000(4326) 共8位 +* @brief extend the wkb format string to EWKB format string; +* you can find the difference between WKB and EWKB format +* at the comments of TryDecodeWKB and TryDecodeEWKB * * @param WKB the wkb format to be extended +* * @param srid_type the srid type to be added in the format * -* @returns the hex format srid_type; +* @returns the EWKB foramt data extended from the input wkb format data; */ std::string SetExtension(const std::string& WKB, SRID srid_type); @@ -149,13 +171,35 @@ SRID ExtractSRID(const std::string& EWKB); SpatialType ExtractType(const std::string& EWKB); /** -* @brief the WKB layout of spatial data: -* 以point为例: 01 01000000 000000000000F03F 0000000000000040 Point(1.0 2.0) -* 01: 1byte 编码方式, 00表示big-endian, 01表示little-endian -* 01000000: 数据类型, 00000001的little endian, 表示point. -* 02 linestring 03 polygon -* 接下来每8个字节代表一个数据, 每16个字节代表一个坐标。 -* 这里主要利用boost/geometry 中的read_wkb检验WKB格式是否正确。 +* @brief the WKB layout of spatial data(little endian): +* Point: 01 01000000 000000000000F03F 0000000000000040 Point(1.0 2.0) +* 01: 1byte 编码方式, 00表示big-endian, 01表示little-endian +* 01000000: 4bytes 数据类型, 00000001的little endian, 表示Point. +* 02 LineString 03 Polygon +* 接下来每4个bytes代表一个数据, 每8个bytes代表一个Point坐标。 +* +* LineString: 01 02000000 03000000 0000000000000000 0000000000000000 +* 0000000000000040 0000000000000040 0000000000000840 000000000000F03F +* LineString(0 0,2 2,3 1) +* 01: 1byte 编码方式 +* 02000000: 4bytes 数据类型 表示LineString +* 03000000: 4bytes 表示在LineString中有三个Point; +* 接下来每8个bytes表示一个Point; +* +* Polygon: 01 03000000 01000000 05000000 0000000000000000 000000000 +* 0000000 0000000000000000 0000000000001C40 0000000000001040 0000000000000040 +* 0000000000000040 0000000000000000 0000000000000000 0000000000000000 +* Polygon((0 0,0 1,1 1,1 0,0 0)) +* 01: 1byte 编码方式 +* 03000000: 4bytes 数据类型 表示LineString +* 01000000: 4bytes 表示在Polygon中有一个ring; +* 05000000: 4bytes +* 接下来每8个bytes表示一个Point; +* +* big endian表示: +* 将上述wkb format以空格隔开的每个部分都由little endian转为big endian; +* +* 这里主要利用boost/geometry/extensions 中的read_wkb检验WKB格式是否正确。 * * @param WKB the string to be parse; * @param type the type of spatial data; @@ -167,30 +211,45 @@ bool TryDecodeWKB(const std::string& WKB, SpatialType type); /** * @brief the EWKB layout of spatial data: -* 以point为例: 01 0100 0020 E6100000 000000000000F03F 0000000000000040 Point(1.0 2.0) +* Point: 01 0100 0020 E6100000 000000000000F03F 0000000000000040 +* SRID=4326 Point(1.0 2.0) * 01: 编码方式, 00表示big-endian, 01表示little-endian -* 0100: 数据类型, 0100代表Point; -* 0020: 表示维度为二维;(?) -* E6010000: SRID -- 4326; 0x000010e6的小端表示; -* 每16个字节代表一个坐标对。 -* 这里首先将EWKB格式转换为WKB格式,再调用TryDecodeWKB; -* EWKB -> WKB WKB -> EWKB的逆变换, 修改EWKB[8] or EWKB[9], 去除SRID信息;(EWKB[10] - EWKB[17]) +* 0100: 数据类型, 0100代表Point; (相比于WKB, 由4bytes表示变为2bytes) +* 0020: 表示维度为二维; +* E6010000: 4bytes SRID -- 4326; 0x000010e6的小端表示; +* 每8个byte代表一个Point。 +* +* LineString: 01 0200 0020 E6100000 03000000 0000000000000000 0000000000000000 +* 0000000000000040 0000000000000040 0000000000000840 000000000000F03F +* SRID=4326 LineString(0 0,2 2,3 1) +* 01: 1byte 编码方式 +* 0200: 2bytes 数据类型 表示LineString +* 0020: 2bytes dimension +* E6010000: 4bytes SRID -- 4326; 0x000010e6的小端表示; +* 03000000: 4bytes 表示在LineString中有三个Point; +* 接下来每8个bytes表示一个Point; +* +* Polygon: 类似; +* 01 0300 0020 e6100000 01000000 05000000 0000000000000000 0000000000000000 +* 0000000000000000 000000000000f03f 000000000000f03f 000000000000f03f 000000000000f03f +* 0000000000000000 0000000000000000 0000000000000000 +* SRID=4326;Polygon((0 0,0 1,1 1,1 0,0 0)) * * @param EWKB the string to be parse; * @param type the type of spatial data; * -* @returns true if EWKB format is valid, false if wkb format is invalid; +* @returns true if WKB format is valid, false if WKB format is invalid; */ bool TryDecodeEWKB(const std::string& EWKB, SpatialType type); /** @brief Implements the Spatial template class. Spatial class now can hold one of - * point, linestring or polygon pointer; + * Point, LineString or Polygon Pointer; */ template class Spatial { - std::unique_ptr> point_; - std::unique_ptr> line_; - std::unique_ptr> polygon_; + std::unique_ptr> Point_; + std::unique_ptr> line_; + std::unique_ptr> Polygon_; SpatialType type_; @@ -233,19 +292,19 @@ class Spatial { */ std::string AsEWKT() const; - /** @brief return the point type pointer */ - std::unique_ptr>& GetPoint() { - return point_; + /** @brief return the Point type Pointer */ + std::unique_ptr>& GetPoint() { + return Point_; } - /** @brief return the line type pointer */ - std::unique_ptr>& GetLine() { + /** @brief return the line type Pointer */ + std::unique_ptr>& GetLine() { return line_; } - /** @brief return the polygon type pointer */ - std::unique_ptr>& GetPolygon() { - return polygon_; + /** @brief return the Polygon type Pointer */ + std::unique_ptr>& GetPolygon() { + return Polygon_; } /** @brief return the type of spatial*/ @@ -290,17 +349,39 @@ class SpatialBase { }; /** - * @brief implements a point spatial class which spatial data is point; + * @brief implements a Point spatial class which spatial data is Point; */ template -class point : public SpatialBase { +class Point : public SpatialBase { std::string EWKB; - bg::model::point point_; + bg::model::point Point_; public: - point(SRID srid, SpatialType type, int construct_type, std::string& content); + /** + * @brief construct Point class from wkb/wkt format; + * + * @param srid the srid of the Point; + * + * @param type type of the spatial data(Point) + * + * @param construct_type 0: WKB 1: wkt; + * + * @param content the wkb/wkt format data; + * + * @exception InputError Thrown if the WKB/WKT format is invalid or the input + * srid dismatch the template srid; + */ + Point(SRID srid, SpatialType type, int construct_type, std::string& content); - explicit point(const std::string& EWKB); + /** + * @brief construct Point class from EWKB format; + * + * @param EWKB the EWKB format data + * + * @param InputError Thrown if the EWKB format is invalid or the input + * srid dismatch the template srid; + */ + explicit Point(const std::string& EWKB); std::string AsEWKB() const override { return EWKB; @@ -313,28 +394,28 @@ class point : public SpatialBase { */ std::string ToString() const; /** - * @brief return point type data; + * @brief return Point type data; */ bg::model::point GetSpatialData() { - return point_; + return Point_; } - bool operator==(const point& other); + bool operator==(const Point& other); }; /** - * @brief implements a linestring spatial class which spatial data is point; + * @brief implements a LineString spatial class which spatial data is Point; */ template -class linestring : public SpatialBase { +class LineString : public SpatialBase { std::string EWKB; - typedef bg::model::point point_; - bg::model::linestring line_; + typedef bg::model::point Point_; + bg::model::linestring line_; public: - linestring(SRID srid, SpatialType type, int construct_type, std::string& content); + LineString(SRID srid, SpatialType type, int construct_type, std::string& content); - explicit linestring(const std::string& EWKB); + explicit LineString(const std::string& EWKB); std::string AsEWKB() const override { return EWKB; @@ -351,22 +432,22 @@ class linestring : public SpatialBase { return line_; } - bool operator==(const linestring& other); + bool operator==(const LineString& other); }; /** - * @brief implements a polygon spatial class which spatial data is point; + * @brief implements a Polygon spatial class which spatial data is Point; */ template -class polygon : public SpatialBase { +class Polygon : public SpatialBase { std::string EWKB; - typedef bg::model::point point; - bg::model::polygon polygon_; + typedef bg::model::point Point; + bg::model::polygon Polygon_; public: - polygon(SRID srid, SpatialType type, int construct_type, std::string& content); + Polygon(SRID srid, SpatialType type, int construct_type, std::string& content); - explicit polygon(const std::string& EWKB); + explicit Polygon(const std::string& EWKB); std::string AsEWKB() const override { return EWKB; @@ -380,9 +461,9 @@ class polygon : public SpatialBase { std::string ToString() const; bg::model::polygon> GetSpatialData() { - return polygon_; + return Polygon_; } - bool operator==(const polygon& other); + bool operator==(const Polygon& other); }; } // namespace lgraph_api diff --git a/include/lgraph/lgraph_types.h b/include/lgraph/lgraph_types.h index 026c6c88bd..6176ec3604 100644 --- a/include/lgraph/lgraph_types.h +++ b/include/lgraph/lgraph_types.h @@ -161,16 +161,16 @@ enum FieldType { INT16 = 3, // 16-bit signed integer INT32 = 4, // 32-bit signed integer INT64 = 5, // 64-bit signed integer - FLOAT = 6, // 32-bit IEEE 754 floating point number - DOUBLE = 7, // 64-bit IEEE 754 floating point number + FLOAT = 6, // 32-bit IEEE 754 floating Point number + DOUBLE = 7, // 64-bit IEEE 754 floating Point number DATE = 8, // Date ranging from 0/1/1 to 9999/12/31 DATETIME = 9, // DateTime ranging from 0000-01-01 00:00:00.000000 to // 9999-12-31 23:59:59.999999 STRING = 10, // string type, in unicode encoding BLOB = 11, // binary byte array - POINT = 12, // point type of spatial data - LINESTRING = 13, // linestring type of spatial data - POLYGON = 14, // polygon type of spatial data + POINT = 12, // Point type of spatial data + LINESTRING = 13, // LineString type of spatial data + POLYGON = 14, // Polygon type of spatial data SPATIAL = 15 // spatial data, it's now unused but may be used in the future. }; @@ -419,32 +419,32 @@ struct FieldData { data.buf = new std::string(buf, buf + s); } - explicit FieldData(const point& p) { + explicit FieldData(const Point& p) { type = FieldType::POINT; data.buf = new std::string(p.AsEWKB()); } - explicit FieldData(const point& p) { + explicit FieldData(const Point& p) { type = FieldType::POINT; data.buf = new std::string(p.AsEWKB()); } - explicit FieldData(const linestring& l) { + explicit FieldData(const LineString& l) { type = FieldType::LINESTRING; data.buf = new std::string(l.AsEWKB()); } - explicit FieldData(const linestring& l) { + explicit FieldData(const LineString& l) { type = FieldType::LINESTRING; data.buf = new std::string(l.AsEWKB()); } - explicit FieldData(const polygon& p) { + explicit FieldData(const Polygon& p) { type = FieldType::POLYGON; data.buf = new std::string(p.AsEWKB()); } - explicit FieldData(const polygon& p) { + explicit FieldData(const Polygon& p) { type = FieldType::POLYGON; data.buf = new std::string(p.AsEWKB()); } @@ -526,50 +526,50 @@ struct FieldData { static inline FieldData String(const char* str) { return FieldData(str); } static inline FieldData String(const char* p, size_t s) { return FieldData(p, s); } - static inline FieldData Point(const ::lgraph_api::point& p) { + static inline FieldData Point(const ::lgraph_api::Point& p) { return FieldData(p); } - static inline FieldData Point(const ::lgraph_api::point& p) {return FieldData(p); } + static inline FieldData Point(const ::lgraph_api::Point& p) {return FieldData(p); } static inline FieldData Point(const std::string& str) { switch (::lgraph_api::ExtractSRID(str)) { case ::lgraph_api::SRID::NUL: throw InputError("Unsupported SRID!"); case ::lgraph_api::SRID::CARTESIAN: - return FieldData(point(str)); + return FieldData(::lgraph_api::Point(str)); case ::lgraph_api::SRID::WSG84: - return FieldData(::lgraph_api::point(str)); + return FieldData(::lgraph_api::Point(str)); default: throw InputError("Unsupported SRID!"); } } - static inline FieldData LineString(const ::lgraph_api::linestring& l) { + static inline FieldData LineString(const ::lgraph_api::LineString& l) { return FieldData(l); } - static inline FieldData LineString(const ::lgraph_api::linestring& l) { + static inline FieldData LineString(const ::lgraph_api::LineString& l) { return FieldData(l); } static inline FieldData LineString(const std::string& str) { switch (::lgraph_api::ExtractSRID(str)) { case ::lgraph_api::SRID::NUL: throw InputError("Unsupported SRID!"); case ::lgraph_api::SRID::CARTESIAN: - return FieldData(linestring(str)); + return FieldData(::lgraph_api::LineString(str)); case ::lgraph_api::SRID::WSG84: - return FieldData(::lgraph_api::linestring(str)); + return FieldData(::lgraph_api::LineString(str)); default: throw InputError("Unsupported SRID!"); } } - static inline FieldData Polygon(const ::lgraph_api::polygon& p) { + static inline FieldData Polygon(const ::lgraph_api::Polygon& p) { return FieldData(p); } - static inline FieldData Polygon(const ::lgraph_api::polygon& p) {return FieldData(p); } + static inline FieldData Polygon(const ::lgraph_api::Polygon& p) {return FieldData(p); } static inline FieldData Polygon(const std::string& str) { switch (::lgraph_api::ExtractSRID(str)) { case ::lgraph_api::SRID::NUL: throw InputError("Unsupported SRID!"); case ::lgraph_api::SRID::CARTESIAN: - return FieldData(polygon(str)); + return FieldData(::lgraph_api::Polygon(str)); case ::lgraph_api::SRID::WSG84: - return FieldData(::lgraph_api::polygon(str)); + return FieldData(::lgraph_api::Polygon(str)); default: throw InputError("Unsupported SRID!"); } @@ -779,40 +779,40 @@ struct FieldData { throw std::bad_cast(); } - inline ::lgraph_api::point<::lgraph_api::Wsg84> AsWsgPoint() const { - if (type == FieldType::POINT) return ::lgraph_api::point + inline ::lgraph_api::Point<::lgraph_api::Wsg84> AsWsgPoint() const { + if (type == FieldType::POINT) return ::lgraph_api::Point <::lgraph_api::Wsg84>(*data.buf); throw std::bad_cast(); } - inline ::lgraph_api::point<::lgraph_api::Cartesian> AsCartesianPoint() const { - if (type == FieldType::POINT) return ::lgraph_api::point + inline ::lgraph_api::Point<::lgraph_api::Cartesian> AsCartesianPoint() const { + if (type == FieldType::POINT) return ::lgraph_api::Point <::lgraph_api::Cartesian>(*data.buf); throw std::bad_cast(); } - inline ::lgraph_api::linestring<::lgraph_api::Wsg84> AsWsgLineString() + inline ::lgraph_api::LineString<::lgraph_api::Wsg84> AsWsgLineString() const { - if (type == FieldType::LINESTRING) return ::lgraph_api::linestring + if (type == FieldType::LINESTRING) return ::lgraph_api::LineString <::lgraph_api::Wsg84>(*data.buf); throw std::bad_cast(); } - inline ::lgraph_api::linestring<::lgraph_api::Cartesian> AsCartesianLineString() + inline ::lgraph_api::LineString<::lgraph_api::Cartesian> AsCartesianLineString() const { - if (type == FieldType::LINESTRING) return ::lgraph_api::linestring + if (type == FieldType::LINESTRING) return ::lgraph_api::LineString <::lgraph_api::Cartesian>(*data.buf); throw std::bad_cast(); } - inline ::lgraph_api::polygon<::lgraph_api::Wsg84> AsWsgPolygon() const { - if (type == FieldType::POLYGON) return ::lgraph_api::polygon + inline ::lgraph_api::Polygon<::lgraph_api::Wsg84> AsWsgPolygon() const { + if (type == FieldType::POLYGON) return ::lgraph_api::Polygon <::lgraph_api::Wsg84>(*data.buf); throw std::bad_cast(); } - inline ::lgraph_api::polygon<::lgraph_api::Cartesian> AsCartesianPolygon() const { - if (type == FieldType::POLYGON) return ::lgraph_api::polygon + inline ::lgraph_api::Polygon<::lgraph_api::Cartesian> AsCartesianPolygon() const { + if (type == FieldType::POLYGON) return ::lgraph_api::Polygon <::lgraph_api::Cartesian>(*data.buf); throw std::bad_cast(); } @@ -874,7 +874,7 @@ struct FieldData { * 2. they are both numeric types * In case 1, the underlying values are compared directly. In case 2, integer * values are converted to int64_t if compared with another integer, or to double - * if compared with a floating-point number. + * if compared with a floating-Point number. */ inline bool operator==(const FieldData& rhs) const { @@ -1095,13 +1095,13 @@ struct FieldData { /** @brief Query if this object is date time */ bool IsDateTime() const { return type == FieldType::DATETIME; } - /** @brief Query if this object is point */ + /** @brief Query if this object is Point */ bool IsPoint() const { return type == FieldType::POINT; } - /** @brief Query if this object is linestring */ + /** @brief Query if this object is LineString */ bool IsLineString() const { return type == FieldType::LINESTRING; } - /** @brief Query if this object is polygon*/ + /** @brief Query if this object is Polygon*/ bool IsPolygon() const { return type == FieldType::POLYGON; } /** @brief Query if this object is spatial*/ @@ -1123,7 +1123,7 @@ struct FieldData { static_assert(sizeof(decltype(data.int64)) == sizeof(decltype(data.buf)) && sizeof(decltype(data.int64)) >= sizeof(decltype(data.dp)), - "sizeof int64_t is supposed to be equal to pointer types"); + "sizeof int64_t is supposed to be equal to Pointer types"); }; /** @brief Specification for a field. */ diff --git a/src/core/data_type.h b/src/core/data_type.h index 7c8ccb757b..96674993c7 100644 --- a/src/core/data_type.h +++ b/src/core/data_type.h @@ -41,12 +41,12 @@ typedef lgraph_api::FieldSpec FieldSpec; typedef lgraph_api::EdgeUid EdgeUid; typedef lgraph_api::Date Date; typedef lgraph_api::DateTime DateTime; -typedef lgraph_api::point PointWsg84; -typedef lgraph_api::point PointCartesian; -typedef lgraph_api::linestring LineStringWsg84; -typedef lgraph_api::linestring LineStringCartesian; -typedef lgraph_api::polygon PolygonWsg84; -typedef lgraph_api::polygon PolygonCartesian; +typedef lgraph_api::Point PointWsg84; +typedef lgraph_api::Point PointCartesian; +typedef lgraph_api::LineString LineStringWsg84; +typedef lgraph_api::LineString LineStringCartesian; +typedef lgraph_api::Polygon PolygonWsg84; +typedef lgraph_api::Polygon PolygonCartesian; typedef lgraph_api::LGraphType ElementType; typedef lgraph_api::Result Result; typedef lgraph_api::EdgeConstraints EdgeConstraints; diff --git a/src/core/field_data_helper.h b/src/core/field_data_helper.h index 747c833da0..83564a96b9 100644 --- a/src/core/field_data_helper.h +++ b/src/core/field_data_helper.h @@ -52,12 +52,12 @@ typedef lgraph_api::FieldData FieldData; typedef lgraph_api::FieldType FieldType; typedef lgraph_api::Date Date; typedef lgraph_api::DateTime DateTime; -typedef lgraph_api::point PointWsg84; -typedef lgraph_api::point PointCartesian; -typedef lgraph_api::linestring LineStringWsg84; -typedef lgraph_api::linestring LineStringCartesian; -typedef lgraph_api::polygon PolygonWsg84; -typedef lgraph_api::polygon PolygonCartesian; +typedef lgraph_api::Point PointWsg84; +typedef lgraph_api::Point PointCartesian; +typedef lgraph_api::LineString LineStringWsg84; +typedef lgraph_api::LineString LineStringCartesian; +typedef lgraph_api::Polygon PolygonWsg84; +typedef lgraph_api::Polygon PolygonCartesian; //=============================== @@ -92,9 +92,9 @@ static constexpr size_t FieldTypeSizes[] = { 8, // datetime 0, // string 0, // blob - 50, // point - 0, // linestring - 0 // polygon + 50, // Point + 0, // LineString + 0 // Polygon }; static constexpr bool IsFixedLengthType[] = { @@ -110,9 +110,9 @@ static constexpr bool IsFixedLengthType[] = { true, // datetime false, // string false, // blob - true, // point - false, // linestring - false // polygon + true, // Point + false, // LineString + false // Polygon }; template @@ -753,13 +753,13 @@ struct FieldDataTypeConvert { // nothing can be converted from bin break; case FieldType::POINT: - // nothing can be converted from point + // nothing can be converted from Point break; case FieldType::LINESTRING: - // nothing can be converted from linestring + // nothing can be converted from LineString break; case FieldType::POLYGON: - // nothing can be converted from polygon; + // nothing can be converted from Polygon; break; case FieldType::SPATIAL: // nothing can be converted from spatial @@ -886,8 +886,8 @@ inline bool TryFieldDataToValueOfFieldType(const FieldData& fd, FieldType ft, Va } case FieldType::POINT: { - // can only convert string to point - // point类型为fixed_length, string类型为variable, 应该不可以直接copy!; + // can only convert string to Point + // Point类型为fixed_length, string类型为variable, 应该不可以直接copy!; // 怎么处理? if (fd.type != FieldType::STRING) return false; const std::string EWKB = *fd.data.buf; @@ -898,7 +898,7 @@ inline bool TryFieldDataToValueOfFieldType(const FieldData& fd, FieldType ft, Va } case FieldType::LINESTRING: { - // can only convert string to linestring + // can only convert string to LineString if (fd.type != FieldType::STRING) return false; const std::string EWKB = *fd.data.buf; if (!::lgraph_api::TryDecodeEWKB(EWKB, ::lgraph_api::SpatialType::LINESTRING)) @@ -908,7 +908,7 @@ inline bool TryFieldDataToValueOfFieldType(const FieldData& fd, FieldType ft, Va } case FieldType::POLYGON: { - // can only convert string to polygon + // can only convert string to Polygon if (fd.type != FieldType::STRING) return false; const std::string EWKB = *fd.data.buf; if (!::lgraph_api::TryDecodeEWKB(EWKB, ::lgraph_api::SpatialType::POLYGON)) @@ -1043,11 +1043,11 @@ inline FieldData ValueToFieldData(const Value& v, FieldType ft) { ::lgraph_api::SRID s = ::lgraph_api::ExtractSRID(ewkb); switch (s) { case ::lgraph_api::SRID::NUL: - throw std::runtime_error("cannot convert to point data!"); + throw std::runtime_error("cannot convert to Point data!"); case ::lgraph_api::SRID::WSG84: - return FieldData(::lgraph_api::point<::lgraph_api::Wsg84>(ewkb)); + return FieldData(::lgraph_api::Point<::lgraph_api::Wsg84>(ewkb)); case ::lgraph_api::SRID::CARTESIAN: - return FieldData(::lgraph_api::point<::lgraph_api::Cartesian>(ewkb)); + return FieldData(::lgraph_api::Point<::lgraph_api::Cartesian>(ewkb)); } } case FieldType::LINESTRING: @@ -1056,11 +1056,11 @@ inline FieldData ValueToFieldData(const Value& v, FieldType ft) { ::lgraph_api::SRID s = ::lgraph_api::ExtractSRID(ewkb); switch (s) { case ::lgraph_api::SRID::NUL: - throw std::runtime_error("cannot convert to point data!"); + throw std::runtime_error("cannot convert to Point data!"); case ::lgraph_api::SRID::WSG84: - return FieldData(::lgraph_api::linestring<::lgraph_api::Wsg84>(ewkb)); + return FieldData(::lgraph_api::LineString<::lgraph_api::Wsg84>(ewkb)); case ::lgraph_api::SRID::CARTESIAN: - return FieldData(::lgraph_api::linestring<::lgraph_api::Cartesian>(ewkb)); + return FieldData(::lgraph_api::LineString<::lgraph_api::Cartesian>(ewkb)); } } case FieldType::POLYGON: @@ -1069,11 +1069,11 @@ inline FieldData ValueToFieldData(const Value& v, FieldType ft) { ::lgraph_api::SRID s = ::lgraph_api::ExtractSRID(ewkb); switch (s) { case ::lgraph_api::SRID::NUL: - throw std::runtime_error("cannot convert to point data!"); + throw std::runtime_error("cannot convert to Point data!"); case ::lgraph_api::SRID::WSG84: - return FieldData(::lgraph_api::polygon<::lgraph_api::Wsg84>(ewkb)); + return FieldData(::lgraph_api::Polygon<::lgraph_api::Wsg84>(ewkb)); case ::lgraph_api::SRID::CARTESIAN: - return FieldData(::lgraph_api::polygon<::lgraph_api::Cartesian>(ewkb)); + return FieldData(::lgraph_api::Polygon<::lgraph_api::Cartesian>(ewkb)); } } case FieldType::SPATIAL: diff --git a/src/core/lgraph_spatial.cpp b/src/core/lgraph_spatial.cpp index 913fd812f1..68821a63e1 100644 --- a/src/core/lgraph_spatial.cpp +++ b/src/core/lgraph_spatial.cpp @@ -18,6 +18,9 @@ namespace lgraph_api { bool Endian(const std::string& EWKB) { + if (EWKB.size() < 42) + throw InputError("wrong wkb/ewkb format"); + std::string endian = EWKB.substr(0, 2); if (endian == "01") { return true; @@ -27,6 +30,8 @@ bool Endian(const std::string& EWKB) { void EndianTansfer(std::string& input) { size_t size = input.size(); + if (size % 2 || size <= 2) + throw InputError("invalid endian transfer data!"); int i = size - 2; std::string output; while (i >= 0) { @@ -37,6 +42,8 @@ void EndianTansfer(std::string& input) { } std::string Srid2Hex(SRID srid_type, size_t width) { + if (width < 4) + throw InputError("invalid width in Srid2Hex!"); int srid = static_cast(srid_type); std::stringstream ioss; std::string s_hex; @@ -55,7 +62,7 @@ std::string Srid2Hex(SRID srid_type, size_t width) { // there's some problem in big2little transform void WkbEndianTransfer(std::string& WKB) { - if(WKB.size() < 42) + if (WKB.size() < 42) throw InputError("wrong wkb type!"); // transfer the first byte which represents the big/little endian; std::string output; @@ -68,9 +75,9 @@ void WkbEndianTransfer(std::string& WKB) { std::string t = WKB.substr(2, 8); EndianTansfer(t); output += t; - size_t start = 10; - // for linestring/polygon we need 4 bytes to represent the number of - // point pairs/rings; + size_t start = 10; + // for LineString/Polygon we need 4 bytes to represent the number of + // Point pairs/rings; if (ExtractType(WKB) == SpatialType::LINESTRING || ExtractType(WKB) == SpatialType::POLYGON) { std::string t = WKB.substr(start, 8); @@ -78,7 +85,7 @@ void WkbEndianTransfer(std::string& WKB) { output += t; start += 8; } - // for polygon, we need extra 4 bytes to represent the number of point + // for Polygon, we need extra 4 bytes to represent the number of Point if (ExtractType(WKB) == SpatialType::POLYGON) { std::string t = WKB.substr(start, 8); EndianTansfer(t); @@ -86,7 +93,7 @@ void WkbEndianTransfer(std::string& WKB) { start += 8; } - // transfer the next n * 8 byte(each represent a point data); + // transfer the next n * 8 byte(each represent a Point data); while (start < WKB.size()) { std::string data = WKB.substr(start, 16); EndianTansfer(data); @@ -98,7 +105,7 @@ void WkbEndianTransfer(std::string& WKB) { } std::string EwkbEndianTransfer(const std::string& EWKB) { - if(EWKB.size() < 50) + if (EWKB.size() < 50) throw InputError("wrong wkb type!"); std::string output; std::string tmp = EWKB.substr(0, 2); // transfer the first byte which represents the type; @@ -107,18 +114,18 @@ std::string EwkbEndianTransfer(const std::string& EWKB) { output += tmp; tmp = EWKB.substr(2, 4); // transfer the next 2 bytes which represents type; - EndianTansfer(tmp); - output += tmp; + EndianTansfer(tmp); + output += tmp; tmp = EWKB.substr(6, 4); // transfer the next 2 bytes which represents dimension; - EndianTansfer(tmp); - output += tmp; + EndianTansfer(tmp); + output += tmp; tmp = EWKB.substr(10, 8); // transfer the next 4 bytes which represents srid; EndianTansfer(tmp); output += tmp; - size_t start = 18; - // for linestring/polygon we need 4 bytes to represent the number of - // point pairs/rings; + size_t start = 18; + // for LineString/Polygon we need 4 bytes to represent the number of + // Point pairs/rings; if (ExtractType(EWKB) == SpatialType::LINESTRING || ExtractType(EWKB) == SpatialType::POLYGON) { std::string t = EWKB.substr(start, 8); @@ -126,15 +133,14 @@ std::string EwkbEndianTransfer(const std::string& EWKB) { output += t; start += 8; } - + // for Polygon, we need extra 4 bytes to represent the number of Point if (ExtractType(EWKB) == SpatialType::POLYGON) { std::string t = EWKB.substr(start, 8); EndianTansfer(t); output += t; start += 8; } - - // for polygon, we need extra 4 bytes to represent the number of point + // transfer the next n * 8 byte(each represent a Point data); while (start < EWKB.size()) { std::string data = EWKB.substr(start, 16); EndianTansfer(data); @@ -151,14 +157,14 @@ std::string SetExtension(const std::string& WKB, SRID srid_type) { // set the dimension information; if (en) - EWKB[8] = '2'; + EWKB[8] = '2'; else EWKB[6] = '2'; // transform srid into hex format in little endian; - std::string s_hex = Srid2Hex(srid_type, 8); + std::string s_hex = Srid2Hex(srid_type, 8); transform(s_hex.begin(), s_hex.end(), s_hex.begin(), ::toupper); - + // if the wkb is in big endian, we need transform it; if (!en) EndianTansfer(s_hex); @@ -169,7 +175,7 @@ std::string SetExtension(const std::string& WKB, SRID srid_type) { } SRID ExtractSRID(const std::string& EWKB) { - // only ewkb format have srid information; + // only ewkb format have srid information; if (EWKB.size() < 50) throw InputError("wrong EWKB type"); @@ -200,7 +206,7 @@ SpatialType ExtractType(const std::string& EWKB) { std::string type = EWKB.substr(2, 8); // if the input format is EWKB type, we only need the first 2 bytes; - if(type[4] != '0' || type[6] != '0') + if (type[4] != '0' || type[6] != '0') type = type.substr(0, 4); // transfer the little endian into big endian for convenient; if (Endian(EWKB)) { @@ -227,23 +233,23 @@ SpatialType ExtractType(const std::string& EWKB) { template bool TryDecodeWKB(const std::string& WKB, SpatialType type) { - typedef bg::model::point point; + typedef bg::model::point Point; switch (type) { case SpatialType::NUL: return false; case SpatialType::POINT: { - point point_; + Point Point_; byte_vector wkb_; if (!bg::hex2wkb(WKB, std::back_inserter(wkb_)) || - !bg::read_wkb(wkb_.begin(), wkb_.end(), point_)) { + !bg::read_wkb(wkb_.begin(), wkb_.end(), Point_)) { return false; } return true; } case SpatialType::LINESTRING: { - bg::model::linestring line_; + bg::model::linestring line_; byte_vector wkb_; if (!bg::hex2wkb(WKB, std::back_inserter(wkb_)) || @@ -254,11 +260,11 @@ bool TryDecodeWKB(const std::string& WKB, SpatialType type) { } case SpatialType::POLYGON: { - bg::model::polygon polygon_; + bg::model::polygon Polygon_; byte_vector wkb_; if (!bg::hex2wkb(WKB, std::back_inserter(wkb_)) || - !bg::read_wkb(wkb_.begin(), wkb_.end(), polygon_)) { + !bg::read_wkb(wkb_.begin(), wkb_.end(), Polygon_)) { return false; } return true; @@ -306,13 +312,13 @@ Spatial::Spatial(SRID srid, SpatialType type, int construct_type, std case SpatialType::NUL: throw std::runtime_error("Unknown Spatial Type"); case SpatialType::POINT: - point_.reset(new point(srid, type, construct_type, content)); + Point_.reset(new Point(srid, type, construct_type, content)); break; case SpatialType::LINESTRING: - line_.reset(new linestring(srid, type, construct_type, content)); + line_.reset(new LineString(srid, type, construct_type, content)); break; case SpatialType::POLYGON: - polygon_.reset(new polygon(srid, type, construct_type, content)); + Polygon_.reset(new Polygon(srid, type, construct_type, content)); break; } } @@ -329,13 +335,13 @@ Spatial::Spatial(const std::string& EWKB) { case SpatialType::NUL: throw InputError("invalid spatial type"); case SpatialType::POINT: - point_.reset(new point(srid, type_, 0, WKB)); + Point_.reset(new Point(srid, type_, 0, WKB)); break; case SpatialType::LINESTRING: - line_.reset(new linestring(srid, type_, 0, WKB)); + line_.reset(new LineString(srid, type_, 0, WKB)); break; case SpatialType::POLYGON: - polygon_.reset(new polygon(srid, type_, 0, WKB)); + Polygon_.reset(new Polygon(srid, type_, 0, WKB)); } } @@ -345,11 +351,11 @@ std::string Spatial::AsEWKB() const { case SpatialType::NUL: return "NUL"; case SpatialType::POINT: - return point_->AsEWKB(); + return Point_->AsEWKB(); case SpatialType::LINESTRING: return line_->AsEWKB(); case SpatialType::POLYGON: - return polygon_->AsEWKB(); + return Polygon_->AsEWKB(); default: throw std::runtime_error("Unknown SRID Type"); } @@ -361,11 +367,11 @@ std::string Spatial::AsEWKT() const { case SpatialType::NUL: return "NUL"; case SpatialType::POINT: - return point_->AsEWKT(); + return Point_->AsEWKT(); case SpatialType::LINESTRING: return line_->AsEWKT(); case SpatialType::POLYGON: - return polygon_->AsEWKT(); + return Polygon_->AsEWKT(); default: throw std::runtime_error("Unknown SRID Type"); } @@ -377,7 +383,7 @@ bool Spatial::operator==(const Spatial &other) { } template -point::point(SRID srid, SpatialType type, int construct_type, std::string& content) +Point::Point(SRID srid, SpatialType type, int construct_type, std::string& content) : SpatialBase(srid, type) { if ((std::is_same::value && srid != SRID::CARTESIAN) || (std::is_same::value && srid != SRID::WSG84)) { @@ -391,9 +397,10 @@ point::point(SRID srid, SpatialType type, int construct_type, std::st byte_vector wkb_; if (!bg::hex2wkb(content, std::back_inserter(wkb_)) || - !bg::read_wkb(wkb_.begin(), wkb_.end(), point_)) { + !bg::read_wkb(wkb_.begin(), wkb_.end(), Point_)) { throw InputError("wrong wkb format: " + content); } + // extend wkb format to ewkb format EWKB = SetExtension(content, GetSrid()); } @@ -402,12 +409,12 @@ point::point(SRID srid, SpatialType type, int construct_type, std::st // 如果WKT格式错误,这里会抛出异常; boost::exception_detail; try { - bg::read_wkt(content, point_); + bg::read_wkt(content, Point_); } catch (const std::exception &ex) { throw InputError("wrong wkt format:" + std::string(ex.what())); } - if (!bg::write_wkb(point_, std::back_inserter(wkb_out))) { + if (!bg::write_wkb(Point_, std::back_inserter(wkb_out))) { throw InputError("wrong wkt format: " + content); } @@ -420,7 +427,7 @@ point::point(SRID srid, SpatialType type, int construct_type, std::st } template -point::point(const std::string& EWKB_) +Point::Point(const std::string& EWKB_) : SpatialBase(ExtractSRID(EWKB_), ExtractType(EWKB_)) { // first, we need to transfer big endian to little endian; SRID srid = ExtractSRID(EWKB_); @@ -437,7 +444,7 @@ point::point(const std::string& EWKB_) byte_vector wkb_; if (!bg::hex2wkb(WKB, std::back_inserter(wkb_)) || - !bg::read_wkb(wkb_.begin(), wkb_.end(), point_)) { + !bg::read_wkb(wkb_.begin(), wkb_.end(), Point_)) { throw InputError("wrong wkb format: " + WKB); } @@ -445,10 +452,10 @@ point::point(const std::string& EWKB_) } template -std::string point::AsEWKT() const { +std::string Point::AsEWKT() const { std::string EWKT; std::stringstream ioss; - ioss << "SRID=" << static_cast(GetSrid()) << ";" << bg::wkt(point_) << std::endl; + ioss << "SRID=" << static_cast(GetSrid()) << ";" << bg::wkt(Point_) << std::endl; std::string tmp; while (ioss >> tmp) { @@ -461,17 +468,17 @@ std::string point::AsEWKT() const { } template -std::string point::ToString() const { +std::string Point::ToString() const { return AsEWKB(); } template -bool point::operator==(const point &other) { +bool Point::operator==(const Point &other) { return AsEWKB() == other.AsEWKB(); } template -linestring::linestring(SRID srid, SpatialType type, +LineString::LineString(SRID srid, SpatialType type, int construct_type, std::string& content) : SpatialBase(srid, type) { if ((std::is_same::value && srid != SRID::CARTESIAN) @@ -508,7 +515,7 @@ int construct_type, std::string& content) } template -linestring::linestring(const std::string& EWKB_) +LineString::LineString(const std::string& EWKB_) : SpatialBase(ExtractSRID(EWKB_), ExtractType(EWKB_)) { SRID srid = ExtractSRID(EWKB_); if ((std::is_same::value && srid != SRID::CARTESIAN) @@ -531,7 +538,7 @@ linestring::linestring(const std::string& EWKB_) } template -std::string linestring::AsEWKT() const { +std::string LineString::AsEWKT() const { std::string EWKT; std::stringstream ioss; @@ -548,17 +555,17 @@ std::string linestring::AsEWKT() const { } template -std::string linestring::ToString() const { +std::string LineString::ToString() const { return AsEWKB(); } template -bool linestring::operator==(const linestring &other) { +bool LineString::operator==(const LineString &other) { return AsEWKB() == other.AsEWKB(); } template -polygon::polygon(SRID srid, SpatialType type, int construct_type, std::string& content) +Polygon::Polygon(SRID srid, SpatialType type, int construct_type, std::string& content) : SpatialBase(srid, type) { if ((std::is_same::value && srid != SRID::CARTESIAN) || (std::is_same::value && srid != SRID::WSG84)) { @@ -571,7 +578,7 @@ polygon::polygon(SRID srid, SpatialType type, int construct_type, std byte_vector wkb_; bg::hex2wkb(content, std::back_inserter(wkb_)); if (!bg::hex2wkb(content, std::back_inserter(wkb_)) || - !bg::read_wkb(wkb_.begin(), wkb_.end(), polygon_)) { + !bg::read_wkb(wkb_.begin(), wkb_.end(), Polygon_)) { throw InputError("wrong wkb format: " + content); } @@ -582,12 +589,12 @@ polygon::polygon(SRID srid, SpatialType type, int construct_type, std std::string wkb_out; try { - bg::read_wkt(content, polygon_); + bg::read_wkt(content, Polygon_); } catch (const std::exception &ex) { throw InputError("wrong wkt format" + std::string(ex.what())); } - if (!bg::write_wkb(polygon_, std::back_inserter(wkb_out))) { + if (!bg::write_wkb(Polygon_, std::back_inserter(wkb_out))) { throw InputError("wrong wkt format: " + content); } @@ -598,7 +605,7 @@ polygon::polygon(SRID srid, SpatialType type, int construct_type, std } template -polygon::polygon(const std::string& EWKB_) +Polygon::Polygon(const std::string& EWKB_) : SpatialBase(ExtractSRID(EWKB_), ExtractType(EWKB_)) { SRID srid = ExtractSRID(EWKB_); if ((std::is_same::value && srid != SRID::CARTESIAN) @@ -616,17 +623,17 @@ polygon::polygon(const std::string& EWKB_) byte_vector wkb_; if (!bg::hex2wkb(WKB, std::back_inserter(wkb_)) || - !bg::read_wkb(wkb_.begin(), wkb_.end(), polygon_)) { + !bg::read_wkb(wkb_.begin(), wkb_.end(), Polygon_)) { throw InputError("wrong wkb format: " + WKB); } } template -std::string polygon::AsEWKT() const { +std::string Polygon::AsEWKT() const { std::string EWKT; std::stringstream ioss; - ioss << "SRID=" << static_cast(GetSrid()) << ";" << bg::wkt(polygon_) << std::endl; + ioss << "SRID=" << static_cast(GetSrid()) << ";" << bg::wkt(Polygon_) << std::endl; std::string tmp; while (ioss >> tmp) { @@ -639,21 +646,21 @@ std::string polygon::AsEWKT() const { } template -std::string polygon::ToString() const { +std::string Polygon::ToString() const { return AsEWKB(); } template -bool polygon::operator==(const polygon &other) { +bool Polygon::operator==(const Polygon &other) { return AsEWKB() == other.AsEWKB(); } -template class point; -template class point; -template class linestring; -template class linestring; -template class polygon; -template class polygon; +template class Point; +template class Point; +template class LineString; +template class LineString; +template class Polygon; +template class Polygon; template class Spatial; template class Spatial; diff --git a/src/core/value.h b/src/core/value.h index 41094293ca..c966f63293 100644 --- a/src/core/value.h +++ b/src/core/value.h @@ -58,44 +58,44 @@ struct TypeCast { // spatial类型不能简单使用memcopy构造; // 这里需要先进行正确性判断吗? template <> -struct TypeCast> { - static lgraph_api::point AsType(void* p, size_t s) { - return lgraph_api::point(std::string((char*)p, s)); +struct TypeCast> { + static lgraph_api::Point AsType(void* p, size_t s) { + return lgraph_api::Point(std::string((char*)p, s)); } }; template <> -struct TypeCast> { - static lgraph_api::point AsType(void* p, size_t s) { - return lgraph_api::point(std::string((char*)p, s)); +struct TypeCast> { + static lgraph_api::Point AsType(void* p, size_t s) { + return lgraph_api::Point(std::string((char*)p, s)); } }; template <> -struct TypeCast> { - static lgraph_api::linestring AsType(void* p, size_t s) { - return lgraph_api::linestring(std::string((char*)p, s)); +struct TypeCast> { + static lgraph_api::LineString AsType(void* p, size_t s) { + return lgraph_api::LineString(std::string((char*)p, s)); } }; template <> -struct TypeCast> { - static lgraph_api::linestring AsType(void* p, size_t s) { - return lgraph_api::linestring(std::string((char*)p, s)); +struct TypeCast> { + static lgraph_api::LineString AsType(void* p, size_t s) { + return lgraph_api::LineString(std::string((char*)p, s)); } }; template <> -struct TypeCast> { - static lgraph_api::polygon AsType(void* p, size_t s) { - return lgraph_api::polygon(std::string((char*)p, s)); +struct TypeCast> { + static lgraph_api::Polygon AsType(void* p, size_t s) { + return lgraph_api::Polygon(std::string((char*)p, s)); } }; template <> -struct TypeCast> { - static lgraph_api::polygon AsType(void* p, size_t s) { - return lgraph_api::polygon(std::string((char*)p, s)); +struct TypeCast> { + static lgraph_api::Polygon AsType(void* p, size_t s) { + return lgraph_api::Polygon(std::string((char*)p, s)); } }; @@ -401,7 +401,7 @@ class Value { } /** - * Gets the pointer to memory block. + * Gets the Pointer to memory block. * * \return Memory block referred to by this */ diff --git a/src/http/http_server.cpp b/src/http/http_server.cpp index 6caae3fb69..9359c9b777 100644 --- a/src/http/http_server.cpp +++ b/src/http/http_server.cpp @@ -111,6 +111,12 @@ nlohmann::json ProtoFieldDataToJson(const ProtoFieldData& data) { return nlohmann::json(data.str()); case ProtoFieldData::kBlob: return nlohmann::json(::lgraph_api::base64::Encode(data.blob())); + case ProtoFieldData::kPoint: + return nlohmann::json(data.point()); + case ProtoFieldData::kLinestring: + return nlohmann::json(data.linestring()); + case ProtoFieldData::kPolygon: + return nlohmann::json(data.polygon()); } FMA_ASSERT(false); return nlohmann::json(); diff --git a/src/protobuf/ha.proto b/src/protobuf/ha.proto index 321ee64581..f112fd1697 100644 --- a/src/protobuf/ha.proto +++ b/src/protobuf/ha.proto @@ -23,6 +23,9 @@ enum ProtoFieldType { DATETIME = 9; STRING = 10; BLOB = 11; + POINT = 12; + LINESTRING = 13; + POLYGON = 14; }; enum ProtoAccessLevel { @@ -46,6 +49,9 @@ message ProtoFieldData { int64 datetime = 9; string str = 10; bytes blob = 11; + string point = 12; + string linestring = 13; + string polygon = 14; } }; diff --git a/src/restful/server/rest_server.cpp b/src/restful/server/rest_server.cpp index 9535a5cc02..efb6d1d85e 100644 --- a/src/restful/server/rest_server.cpp +++ b/src/restful/server/rest_server.cpp @@ -360,6 +360,15 @@ web::json::value ProtoFieldDataToJson(const ProtoFieldData& data) { return web::json::value(_TU(data.str())); case ProtoFieldData::kBlob: return web::json::value(_TU(::lgraph_api::base64::Encode(data.blob()))); + case ProtoFieldData::kPoint: + // TODO(shw): string(_TU(Point(data.point()).ToString())); + return web::json::value::string(_TU(data.point())); + case ProtoFieldData::kLinestring: + // TODO(shw): string(_TU(LineString(data.linestring()).ToString())); + return web::json::value::string(_TU(data.linestring())); + case ProtoFieldData::kPolygon: + // TODO(shw): string(_TU(Polygon(data.polygon()).ToString())); + return web::json::value::string(_TU(data.polygon())); } FMA_ASSERT(false); return web::json::value::null(); diff --git a/src/server/proto_convert.h b/src/server/proto_convert.h index 40ce3c5889..823ec70682 100644 --- a/src/server/proto_convert.h +++ b/src/server/proto_convert.h @@ -59,6 +59,14 @@ struct FieldDataConvert { return FieldData::String(std::move(*fd.release_str())); case ProtoFieldData::kBlob: return FieldData::Blob(std::move(*fd.release_blob())); + case ProtoFieldData::kPoint: + // TODO(shw): 这里有必要在spatial中实现std::string&& 移动语义吗 + // string类型应该只涉及传参,不涉及深浅拷贝。 + return FieldData::Point(std::move(*fd.release_point())); + case ProtoFieldData::kLinestring: + return FieldData::LineString(std::move(*fd.release_linestring())); + case ProtoFieldData::kPolygon: + return FieldData::Polygon(std::move(*fd.release_polygon())); } FMA_ASSERT(false); return FieldData(); @@ -90,6 +98,12 @@ struct FieldDataConvert { return FieldData::String(fd.str()); case ProtoFieldData::kBlob: return FieldData::Blob(fd.blob()); + case ProtoFieldData::kPoint: + return FieldData::Point(fd.point()); + case ProtoFieldData::kLinestring: + return FieldData::LineString(fd.linestring()); + case ProtoFieldData::kPolygon: + return FieldData::Polygon(fd.polygon()); } FMA_ASSERT(false); return FieldData(); @@ -122,11 +136,11 @@ struct FieldDataConvert { case FieldType::BLOB: return ret->set_blob(std::move(*fd.data.buf)); case FieldType::POINT: - + return ret->set_point(std::move(*fd.data.buf)); case FieldType::LINESTRING: - + return ret->set_linestring(std::move(*fd.data.buf)); case FieldType::POLYGON: - + return ret->set_polygon(std::move(*fd.data.buf)); case FieldType::SPATIAL: return; } @@ -160,11 +174,11 @@ struct FieldDataConvert { case FieldType::BLOB: return ret->set_blob(*fd.data.buf); case FieldType::POINT: - // TODO(shw): realize convert of point type between fielddata and protofielddata; + return ret->set_point(*fd.data.buf); case FieldType::LINESTRING: - // TODO(shw): realize convert of linestring type between fielddata and protofielddata; + return ret->set_linestring(*fd.data.buf); case FieldType::POLYGON: - // TODO(shw): realize convert of polygon type between fielddata and protofielddata; + return ret->set_polygon(*fd.data.buf); case FieldType::SPATIAL: return; } diff --git a/test/test_field_data_helper.cpp b/test/test_field_data_helper.cpp index b915e9eddf..d7ed7b6311 100644 --- a/test/test_field_data_helper.cpp +++ b/test/test_field_data_helper.cpp @@ -241,7 +241,7 @@ TEST_F(TestFieldDataHelper, ParseStringIntoStorageType) { _CHECK_PARSE_STRING_FAIL(BLOB, "kkk"); _CHECK_PARSE_STRING_FAIL(POINT, "123absd"); _CHECK_PARSE_STRING_FAIL(LINESTRING, "0.23124325"); - _CHECK_PARSE_STRING_FAIL(POINT, "asdjasncioo"); + _CHECK_PARSE_STRING_FAIL(POLYGON, "asdjasncioo"); } TEST_F(TestFieldDataHelper, FieldDataTypeConvert) { @@ -274,7 +274,7 @@ TEST_F(TestFieldDataHelper, FieldDataTypeConvert) { _TEST_FD_CONVERT(INT64, 10000000000L, INT32, 1, false); // out of range _TEST_FD_CONVERT(STRING, "111", INT64, 1, false); _TEST_FD_CONVERT(BLOB, "111", INT64, 1, false); - // floating points can be converted from fp or int types + // floating Points can be converted from fp or int types _TEST_FD_CONVERT(INT8, 127, FLOAT, 127, true); _TEST_FD_CONVERT(INT32, 1 << 30, DOUBLE, 1 << 30, true); _TEST_FD_CONVERT(FLOAT, 0.25, DOUBLE, 0.25, true); @@ -289,17 +289,17 @@ TEST_F(TestFieldDataHelper, FieldDataTypeConvert) { // testing spatial data; std::string EWKB = "0101000020E6100000000000000000F03F0000000000000040"; _TEST_FD_CONVERT(STRING, EWKB, POINT, - ::lgraph_api::point<::lgraph_api::Wsg84>(EWKB).AsEWKB(), true); + ::lgraph_api::Point<::lgraph_api::Wsg84>(EWKB).AsEWKB(), true); EWKB = "0102000020231C00000300000000000000000000000000000000000000000" "000000000004000000000000000400000000000000840000000000000F03F"; _TEST_FD_CONVERT(STRING, EWKB, LINESTRING, - ::lgraph_api::linestring<::lgraph_api::Cartesian>(EWKB).AsEWKB(), + ::lgraph_api::LineString<::lgraph_api::Cartesian>(EWKB).AsEWKB(), true); EWKB = "0103000020E6100000010000000500000000000000000000000000000000" "00000000000000000000000000000000001C400000000000001040000000000000" "00400000000000000040000000000000000000000000000000000000000000000000"; _TEST_FD_CONVERT(STRING, EWKB, POLYGON, - ::lgraph_api::polygon<::lgraph_api::Wsg84>(EWKB).AsEWKB(), + ::lgraph_api::Polygon<::lgraph_api::Wsg84>(EWKB).AsEWKB(), true); // string can only be converted from string _TEST_FD_CONVERT(INT8, 127, STRING, "", false); @@ -357,7 +357,7 @@ TEST_F(TestFieldDataHelper, TryFieldDataToValueOfFieldType) { _TEST_FD_TO_VALUE_OF_FT(BLOB, "hello", BLOB, "hello", true); _TEST_FD_TO_VALUE_OF_FT(STRING, ::lgraph_api::base64::Encode("hello"), BLOB, "hello", true); - // testing point; + // testing Point; { std::string EWKB = "0101000020E6100000000000000000F03F0000000000000040"; FieldData fd = FieldData(EWKB); @@ -366,7 +366,7 @@ TEST_F(TestFieldDataHelper, TryFieldDataToValueOfFieldType) { UT_EXPECT_EQ(v.AsType(), PointWsg84(EWKB).AsEWKB()); } - // testing linestring; + // testing LineString; { std::string EWKB = "0102000020231C00000300000000000000000000000000000000000000000" "000000000004000000000000000400000000000000840000000000000F03F"; @@ -376,7 +376,7 @@ TEST_F(TestFieldDataHelper, TryFieldDataToValueOfFieldType) { UT_EXPECT_EQ(v.AsType(), LineStringCartesian(EWKB).AsEWKB()); } - // testing polygon + // testing Polygon { std::string EWKB = "0103000020E6100000010000000500000000000000000000000000000000" "00000000000000000000000000000000001C400000000000001040000000000000" @@ -503,7 +503,7 @@ TEST_F(TestFieldDataHelper, ValueCompare) { _TEST_VALUE_COMPARE(BLOB, std::string(3, 'a'), std::string(4, 'a'), -1); _TEST_VALUE_COMPARE(BLOB, std::string(30, 'a'), std::string(4, 'a'), 1); _TEST_VALUE_COMPARE(BLOB, std::string(30, 'a'), std::string(4, 'a'), 1); - // testing point(compare string); + // testing Point(compare string); { std::string EWKB1 = "0101000020E6100000000000000000F03F0000000000000040"; std::string EWKB2 = "0101000020231C0000000000000000F03F000000000000F03F"; diff --git a/test/test_lgraph_spatial.cpp b/test/test_lgraph_spatial.cpp index b5d6970522..d116da833c 100644 --- a/test/test_lgraph_spatial.cpp +++ b/test/test_lgraph_spatial.cpp @@ -43,12 +43,12 @@ static void CreateSampleDB(const std::string& dir, bool detach_property) { "spatial", std::vector( {FieldSpec("id", FieldType::INT32, false), - FieldSpec("string2point", FieldType::STRING, false), - FieldSpec("point", FieldType::POINT, false), + FieldSpec("string2Point", FieldType::STRING, false), + FieldSpec("Point", FieldType::POINT, false), FieldSpec("string2line", FieldType::STRING, false), - FieldSpec("linestring", FieldType::LINESTRING, true), - FieldSpec("string2polygon", FieldType::POLYGON, true), - FieldSpec("polygon", FieldType::POLYGON, true)}), + FieldSpec("LineString", FieldType::LINESTRING, true), + FieldSpec("string2Polygon", FieldType::POLYGON, true), + FieldSpec("Polygon", FieldType::POLYGON, true)}), true, vo)); EdgeOptions options; @@ -69,24 +69,24 @@ static void CreateSampleDB(const std::string& dir, bool detach_property) { VertexId v0 = txn.AddVertex( std::string("spatial"), - std::vector({"id", "string2point", "point", - "string2line", "linestring", "string2polygon", "polygon"}), + std::vector({"id", "string2Point", "Point", + "string2line", "LineString", "string2Polygon", "Polygon"}), std::vector({"1", Point_EWKB, Point_EWKB, Line_EWKB, Line_EWKB, Polygon_EWKB, Polygon_EWKB})); // 这里的primary_key不能相同; VertexId v1 = txn.AddVertex( std::string("spatial"), - std::vector({"id", "string2point", "point", - "string2line", "linestring", "string2polygon", "polygon"}), + std::vector({"id", "string2Point", "Point", + "string2line", "LineString", "string2Polygon", "Polygon"}), std::vector({"2", Point_EWKB, Point_EWKB, Line_EWKB, Line_EWKB, Polygon_EWKB, Polygon_EWKB})); // testting parse and set fielddata; VertexId v2 = txn.AddVertex( std::string("spatial"), - std::vector({"id", "string2point", "point", - "string2line", "linestring", "string2polygon", "polygon"}), + std::vector({"id", "string2Point", "Point", + "string2line", "LineString", "string2Polygon", "Polygon"}), std::vector({FieldData::Int32(3), FieldData::String(Point_EWKB), FieldData::Point(Point_EWKB), FieldData::String(Line_EWKB), FieldData::LineString(Line_EWKB), FieldData::String(Polygon_EWKB), @@ -114,15 +114,15 @@ static void TestSampleDB(const std::string& dir, bool detach_property) { "spatial", std::vector( {FieldSpec("id", FieldType::INT32, false), - FieldSpec("point", FieldType::POINT, true), + FieldSpec("Point", FieldType::POINT, true), FieldSpec("line", FieldType::LINESTRING, true), - FieldSpec("polygon", FieldType::POLYGON, true)}), + FieldSpec("Polygon", FieldType::POLYGON, true)}), true, vo)); { auto txn = lg.CreateWriteTxn(); UT_EXPECT_ANY_THROW(txn.AddVertex( std::string("spatial"), - std::vector({"id", "point", "line", "polygon"}), + std::vector({"id", "Point", "line", "Polygon"}), std::vector({"1", "aabbcsadsafasda", "01020000201234000003000000000000000000000000000000000000000" @@ -133,7 +133,7 @@ static void TestSampleDB(const std::string& dir, bool detach_property) { UT_EXPECT_ANY_THROW( txn.AddVertex( std::string("spatial"), - std::vector({"id", "point", "line", "polygon"}), + std::vector({"id", "Point", "line", "Polygon"}), std::vector({FieldData::Int32(1), FieldData::Point("asdasjcabkdsv"), FieldData::LineString("01020000201234000003000000000000000000000000000000000000000" "00000000000004000000000000000400000000000000840000000000000F03F"), @@ -146,16 +146,16 @@ static void TestSampleDB(const std::string& dir, bool detach_property) { "spatial_transform", std::vector( {FieldSpec("id", FieldType::INT32, false), - FieldSpec("point2string", FieldType::STRING, true), + FieldSpec("Point2string", FieldType::STRING, true), FieldSpec("line2string", FieldType::STRING, true), - FieldSpec("polygon2string", FieldType::STRING, true)}), + FieldSpec("Polygon2string", FieldType::STRING, true)}), true, vo)); auto txn = lg.CreateWriteTxn(); txn.AddVertex( std::string("spatial_transform"), - std::vector({"id", "point2string", "line2string", "polygon2string"}), + std::vector({"id", "Point2string", "line2string", "Polygon2string"}), std::vector({"1", "aabbcsadsafasda", "01020000201234000003000000000000000000000000000000000000000" @@ -167,9 +167,9 @@ static void TestSampleDB(const std::string& dir, bool detach_property) { size_t n_changed = 0; UT_EXPECT_ANY_THROW(lg.AlterLabelModFields( "spatial_transform", - std::vector({FieldSpec("point2string", FieldType::POINT, true), - FieldSpec("linestring2string", FieldType::LINESTRING, true), - FieldSpec("polygon2string", FieldType::POLYGON, true)}), + std::vector({FieldSpec("Point2string", FieldType::POINT, true), + FieldSpec("LineString2string", FieldType::LINESTRING, true), + FieldSpec("Polygon2string", FieldType::POLYGON, true)}), true, &n_changed)); } } @@ -180,18 +180,18 @@ TEST_P(TestSpatial, Spatial) { { UT_LOG() << "Testing encode and decode"; - Spatial point_w(SRID::WSG84, SpatialType::POINT, 0, + Spatial Point_w(SRID::WSG84, SpatialType::POINT, 0, "0101000000000000000000F03F0000000000000040"); // 输出全部为大写字母 - UT_EXPECT_EQ(point_w.AsEWKB(), "0101000020E6100000000000000000F03F0000000000000040"); - UT_EXPECT_EQ(point_w.AsEWKT(), "SRID=4326;POINT(1 2)"); + UT_EXPECT_EQ(Point_w.AsEWKB(), "0101000020E6100000000000000000F03F0000000000000040"); + UT_EXPECT_EQ(Point_w.AsEWKT(), "SRID=4326;POINT(1 2)"); // testing wrong wkb format; UT_EXPECT_ANY_THROW(Spatial(SRID::WSG84, SpatialType::POINT, 0, "1111111")); - Spatial point_c(SRID::CARTESIAN, SpatialType::POINT, 1, "POINT(1.0 1.0)"); - UT_EXPECT_EQ(point_c.AsEWKB(), "0101000020231C0000000000000000F03F000000000000F03F"); - UT_EXPECT_EQ(point_c.AsEWKT(), "SRID=7203;POINT(1 1)"); + Spatial Point_c(SRID::CARTESIAN, SpatialType::POINT, 1, "POINT(1.0 1.0)"); + UT_EXPECT_EQ(Point_c.AsEWKB(), "0101000020231C0000000000000000F03F000000000000F03F"); + UT_EXPECT_EQ(Point_c.AsEWKT(), "SRID=7203;POINT(1 1)"); // testing wrong wkt format; UT_EXPECT_ANY_THROW(Spatial(SRID::CARTESIAN, SpatialType::POINT, 1, @@ -219,25 +219,25 @@ TEST_P(TestSpatial, Spatial) { UT_EXPECT_ANY_THROW(Spatial(SRID::CARTESIAN, SpatialType::LINESTRING, 1, "LINE(0 0,2 2,3 1)")); - Spatial polygon_w(SRID::WSG84, SpatialType::POLYGON, 0, + Spatial Polygon_w(SRID::WSG84, SpatialType::POLYGON, 0, "0103000000010000000500000000000000000000000000000000000000000" "00000000000000000000000001C4000000000000010400000000000000040" "0000000000000040000000000000000000000000000000000000000000000000"); - UT_EXPECT_EQ(polygon_w.AsEWKB(), "0103000020E6100000010000000500000000000000000000000" + UT_EXPECT_EQ(Polygon_w.AsEWKB(), "0103000020E6100000010000000500000000000000000000000" "00000000000000000000000000000000000000000001C400000000000001040000000000000004000000" "00000000040000000000000000000000000000000000000000000000000"); - UT_EXPECT_EQ(polygon_w.AsEWKT(), "SRID=4326;POLYGON((0 0,0 7,4 2,2 0,0 0))"); + UT_EXPECT_EQ(Polygon_w.AsEWKT(), "SRID=4326;POLYGON((0 0,0 7,4 2,2 0,0 0))"); UT_EXPECT_ANY_THROW(Spatial(SRID::WSG84, SpatialType::POLYGON, 1, "abcde")); - Spatial polygon_c(SRID::CARTESIAN, SpatialType::POLYGON, 1, + Spatial Polygon_c(SRID::CARTESIAN, SpatialType::POLYGON, 1, "POLYGON((0 0,0 7,4 2,2 0,0 0))"); - UT_EXPECT_EQ(polygon_c.AsEWKB(), "0103000020231C0000010000000500000000000000000000000" + UT_EXPECT_EQ(Polygon_c.AsEWKB(), "0103000020231C0000010000000500000000000000000000000" "00000000000000000000000000000000000000000001C400000000000001040000000000000004000000" "00000000040000000000000000000000000000000000000000000000000"); - UT_EXPECT_EQ(polygon_c.AsEWKT(), "SRID=7203;POLYGON((0 0,0 7,4 2,2 0,0 0))"); + UT_EXPECT_EQ(Polygon_c.AsEWKT(), "SRID=7203;POLYGON((0 0,0 7,4 2,2 0,0 0))"); UT_EXPECT_ANY_THROW(Spatial(SRID::WSG84, SpatialType::POLYGON, 1, "POLYGON(122)")); UT_EXPECT_ANY_THROW(Spatial(SRID::CARTESIAN, SpatialType::POLYGON, 1, @@ -270,60 +270,60 @@ TEST_P(TestSpatial, Spatial) { { UT_LOG() << "Testing constructor"; - std::string point_EWKB = "0101000020E6100000000000000000F03F000000000000F03F"; + std::string Point_EWKB = "0101000020E6100000000000000000F03F000000000000F03F"; std::string line_WKT = "LINESTRING(0 0,2 2,3 1)"; - point p(point_EWKB); - UT_EXPECT_ANY_THROW(point p_(point_EWKB)); - UT_EXPECT_ANY_THROW(linestring l_(SRID::CARTESIAN, SpatialType::LINESTRING, 1, + Point p(Point_EWKB); + UT_EXPECT_ANY_THROW(Point p_(Point_EWKB)); + UT_EXPECT_ANY_THROW(LineString l_(SRID::CARTESIAN, SpatialType::LINESTRING, 1, line_WKT)); - UT_EXPECT_EQ(p.AsEWKB(), point_EWKB); + UT_EXPECT_EQ(p.AsEWKB(), Point_EWKB); UT_EXPECT_EQ(p.AsEWKT(), "SRID=4326;POINT(1 1)"); } { - UT_LOG() << "Testing point big endian"; - std::string big_point_wkb = "00000000013FF00000000000003FF0000000000000"; - std::string big_point_EWKB = "0000012000000010E63FF00000000000003FF0000000000000"; - std::string little_point_EWKB = "0101000020E6100000000000000000F03F000000000000F03F"; - std::string little_point_wkb = "0101000000000000000000F03F000000000000F03F"; - point p(SRID::WSG84, SpatialType::POINT, 0, big_point_wkb); - point p_(big_point_EWKB); - UT_EXPECT_EQ(p.AsEWKB(), little_point_EWKB); + UT_LOG() << "Testing Point big endian"; + std::string big_Point_wkb = "00000000013FF00000000000003FF0000000000000"; + std::string big_Point_EWKB = "0000012000000010E63FF00000000000003FF0000000000000"; + std::string little_Point_EWKB = "0101000020E6100000000000000000F03F000000000000F03F"; + std::string little_Point_wkb = "0101000000000000000000F03F000000000000F03F"; + Point p(SRID::WSG84, SpatialType::POINT, 0, big_Point_wkb); + Point p_(big_Point_EWKB); + UT_EXPECT_EQ(p.AsEWKB(), little_Point_EWKB); UT_EXPECT_EQ(p.AsEWKT(), "SRID=4326;POINT(1 1)"); - UT_EXPECT_EQ(p_.AsEWKB(), little_point_EWKB); + UT_EXPECT_EQ(p_.AsEWKB(), little_Point_EWKB); UT_EXPECT_EQ(p_.AsEWKT(), "SRID=4326;POINT(1 1)"); - UT_LOG() << "Testing linestring big endian"; - std::string big_linestring_wkb = "0102000000030000000000000000000000000000" + UT_LOG() << "Testing LineString big endian"; + std::string big_LineString_wkb = "0102000000030000000000000000000000000000" "0000000000000000000000004000000000000000400000000000000840000000000000F03F"; - // std::string little_linestring_wkb = big_linestring_wkb; - std::string big_linestring_EWKB = "0102000020E61000000300000000000000000000000" + // std::string little_LineString_wkb = big_LineString_wkb; + std::string big_LineString_EWKB = "0102000020E61000000300000000000000000000000" "000000000000000000000000000004000000000000000400000000000000840000000000000F03F"; - std::string little_linestring_EWKB = big_linestring_EWKB; - WkbEndianTransfer(big_linestring_wkb); - big_linestring_EWKB = EwkbEndianTransfer(big_linestring_EWKB); - linestring l(SRID::WSG84, SpatialType::LINESTRING, 0, big_linestring_wkb); - linestring l_(big_linestring_EWKB); - UT_EXPECT_EQ(l.AsEWKB(), little_linestring_EWKB); + std::string little_LineString_EWKB = big_LineString_EWKB; + WkbEndianTransfer(big_LineString_wkb); + big_LineString_EWKB = EwkbEndianTransfer(big_LineString_EWKB); + LineString l(SRID::WSG84, SpatialType::LINESTRING, 0, big_LineString_wkb); + LineString l_(big_LineString_EWKB); + UT_EXPECT_EQ(l.AsEWKB(), little_LineString_EWKB); UT_EXPECT_EQ(l.AsEWKT(), "SRID=4326;LINESTRING(0 0,2 2,3 1)"); - UT_EXPECT_EQ(l_.AsEWKB(), little_linestring_EWKB); + UT_EXPECT_EQ(l_.AsEWKB(), little_LineString_EWKB); UT_EXPECT_EQ(l_.AsEWKT(), "SRID=4326;LINESTRING(0 0,2 2,3 1)"); - UT_LOG() << "Testing polygon big endian"; - std::string big_polygon_wkb = "010300000001000000050000000000000000000000000000000" + UT_LOG() << "Testing Polygon big endian"; + std::string big_Polygon_wkb = "010300000001000000050000000000000000000000000000000" "000000000000000000000000000000000001C4000000000000010400000000000000040" "0000000000000040000000000000000000000000000000000000000000000000"; - std::string big_polygon_ewkb = "0103000020E6100000010000000500000000000000000000000" + std::string big_Polygon_ewkb = "0103000020E6100000010000000500000000000000000000000" "00000000000000000000000000000000000000000001C4000000000000010400000000000000040000" "0000000000040000000000000000000000000000000000000000000000000"; - std::string little_polygon_ewkb = big_polygon_ewkb; - WkbEndianTransfer(big_polygon_wkb); - big_polygon_ewkb = EwkbEndianTransfer(big_polygon_ewkb); - polygon po(SRID::WSG84, SpatialType::POLYGON, 0, big_polygon_wkb); - polygon po_(big_polygon_ewkb); - UT_EXPECT_EQ(po.AsEWKB(), little_polygon_ewkb); + std::string little_Polygon_ewkb = big_Polygon_ewkb; + WkbEndianTransfer(big_Polygon_wkb); + big_Polygon_ewkb = EwkbEndianTransfer(big_Polygon_ewkb); + Polygon po(SRID::WSG84, SpatialType::POLYGON, 0, big_Polygon_wkb); + Polygon po_(big_Polygon_ewkb); + UT_EXPECT_EQ(po.AsEWKB(), little_Polygon_ewkb); UT_EXPECT_EQ(po.AsEWKT(), "SRID=4326;POLYGON((0 0,0 7,4 2,2 0,0 0))"); - UT_EXPECT_EQ(po_.AsEWKB(), little_polygon_ewkb); + UT_EXPECT_EQ(po_.AsEWKB(), little_Polygon_ewkb); UT_EXPECT_EQ(po_.AsEWKT(), "SRID=4326;POLYGON((0 0,0 7,4 2,2 0,0 0))"); } } @@ -337,32 +337,32 @@ TEST_P(TestSpatial, Spatial_Schema) { true, std::vector( {FieldSpec("id", FieldType::INT32, false), - FieldSpec("point", FieldType::POINT, false), - FieldSpec("linestring", FieldType::LINESTRING, true), - FieldSpec("polygon", FieldType::POLYGON, true), - FieldSpec("string2point", FieldType::STRING, true), + FieldSpec("Point", FieldType::POINT, false), + FieldSpec("LineString", FieldType::LINESTRING, true), + FieldSpec("Polygon", FieldType::POLYGON, true), + FieldSpec("string2Point", FieldType::STRING, true), FieldSpec("string2line", FieldType::STRING, false), - FieldSpec("string2polygon", FieldType::STRING, true)}), + FieldSpec("string2Polygon", FieldType::STRING, true)}), "id", {}); std::map fields = s1.GetFieldSpecsAsMap(); // add fields; { Schema s2(s1); - s2.AddFields(std::vector({FieldSpec("point2", FieldType::POINT, false)})); - UT_EXPECT_TRUE(s2.GetFieldExtractor("point2")->GetFieldSpec() == - FieldSpec("point2", FieldType::POINT, false)); + s2.AddFields(std::vector({FieldSpec("Point2", FieldType::POINT, false)})); + UT_EXPECT_TRUE(s2.GetFieldExtractor("Point2")->GetFieldSpec() == + FieldSpec("Point2", FieldType::POINT, false)); auto fmap = s2.GetFieldSpecsAsMap(); UT_EXPECT_EQ(fmap.size(), fields.size() + 1); - fmap.erase("point2"); + fmap.erase("Point2"); UT_EXPECT_TRUE(fmap == fields); } // mod fields; { Schema s2(s1); - std::vector mod = {FieldSpec("string2point", FieldType::POINT, false), + std::vector mod = {FieldSpec("string2Point", FieldType::POINT, false), FieldSpec("string2line", FieldType::LINESTRING, false), - FieldSpec("string2polygon", FieldType::POLYGON, false)}; + FieldSpec("string2Polygon", FieldType::POLYGON, false)}; s2.ModFields(mod); UT_EXPECT_TRUE(!s2.HasBlob()); auto fmap = s2.GetFieldSpecsAsMap(); @@ -377,7 +377,7 @@ TEST_P(TestSpatial, Spatial_Schema) { // del fields; { Schema s2(s1); - std::vector to_del = {"point", "linestring", "polygon"}; + std::vector to_del = {"Point", "LineString", "Polygon"}; s2.DelFields(to_del); UT_EXPECT_TRUE(!s2.HasBlob()); auto fmap = s2.GetFieldSpecsAsMap(); @@ -395,12 +395,12 @@ TEST_P(TestSpatial, Spatial_Schema) { UT_LOG() << "Testing set spatial schema and add vertex"; { auto txn = graph.CreateReadTxn(); - UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("point")) == FieldData::Point + UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("Point")) == FieldData::Point ("0101000020E6100000000000000000F03F0000000000000040")); - UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("linestring")) == FieldData::LineString + UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("LineString")) == FieldData::LineString ("0102000020E610000003000000000000000000000000000000000000000" "00000000000004000000000000000400000000000000840000000000000F03F")); - UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("polygon")) == FieldData::Polygon + UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("Polygon")) == FieldData::Polygon ("0103000020231C0000010000000500000000000000000000000" "00000000000000000000000000000000000000000001C400000000000001040000000000000004000000" "00000000040000000000000000000000000000000000000000000000000")); @@ -411,15 +411,15 @@ TEST_P(TestSpatial, Spatial_Schema) { size_t n_changed = 0; UT_EXPECT_TRUE(graph.AlterLabelAddFields( "spatial", - std::vector({FieldSpec("point2", FieldType::POINT, true), - FieldSpec("linestring2", FieldType::LINESTRING, true), - FieldSpec("polygon2", FieldType::POLYGON, true)}), + std::vector({FieldSpec("Point2", FieldType::POINT, true), + FieldSpec("LineString2", FieldType::LINESTRING, true), + FieldSpec("Polygon2", FieldType::POLYGON, true)}), std::vector({FieldData::Point ("0101000020231C0000000000000000F03F0000000000000040"), FieldData(), FieldData()}), true, &n_changed)); UT_EXPECT_EQ(n_changed, 3); auto txn = graph.CreateReadTxn(); - UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("point2")) == FieldData::Point + UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("Point2")) == FieldData::Point ("0101000020231C0000000000000000F03F0000000000000040")); } @@ -428,13 +428,13 @@ TEST_P(TestSpatial, Spatial_Schema) { size_t n_changed = 0; UT_EXPECT_TRUE(graph.AlterLabelModFields( "spatial", - std::vector({FieldSpec("string2point", FieldType::POINT, false), + std::vector({FieldSpec("string2Point", FieldType::POINT, false), FieldSpec("string2line", FieldType::LINESTRING, false), - FieldSpec("string2polygon", FieldType::POLYGON, false)}), + FieldSpec("string2Polygon", FieldType::POLYGON, false)}), true, &n_changed)); UT_EXPECT_EQ(n_changed, 3); auto txn = graph.CreateReadTxn(); - UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("string2point")) == FieldData::Point + UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("string2Point")) == FieldData::Point ("0101000020E6100000000000000000F03F0000000000000040")); UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("string2line")) == FieldData::LineString ("0102000020E610000003000000000000000000000000000000000000000" @@ -445,12 +445,12 @@ TEST_P(TestSpatial, Spatial_Schema) { { size_t n_changed = 0; UT_EXPECT_TRUE(graph.AlterLabelDelFields("spatial", std::vector - ({"point", "linestring", "polygon"}), true, &n_changed)); + ({"Point", "LineString", "Polygon"}), true, &n_changed)); UT_EXPECT_EQ(n_changed, 3); auto txn = graph.CreateReadTxn(); - UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("point")) == FieldData()); - UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("linestring")) == FieldData()); - UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("polygon")) == FieldData()); + UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("Point")) == FieldData()); + UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("LineString")) == FieldData()); + UT_EXPECT_TRUE(txn.GetVertexField(0, std::string("Polygon")) == FieldData()); } } diff --git a/test/test_proto_convert.cpp b/test/test_proto_convert.cpp index 53e2d9803b..8d51ecbffa 100644 --- a/test/test_proto_convert.cpp +++ b/test/test_proto_convert.cpp @@ -52,6 +52,15 @@ TEST_F(TestProtoConvert, ProtoConvert) { auto fd2 = FieldDataConvert::ToLGraphT(pfd); UT_EXPECT_EQ(fd.AsString(), fd2.AsString()); } + { + FieldData fd(PointWsg84(std::string("0101000020E6100000000000000000" + "F03F0000000000000040"))); + FieldDataConvert::FromLGraphT(fd, &pfd); + UT_EXPECT_TRUE(fd.AsWsgPoint() == PointWsg84(pfd.point())); + UT_EXPECT_TRUE(pfd.has_point()); + auto fd2 = FieldDataConvert::ToLGraphT(pfd); + UT_EXPECT_TRUE(fd.AsWsgPoint() == fd2.AsWsgPoint()); + } { FieldData fd; FieldDataConvert::FromLGraphT(fd, &pfd); @@ -88,6 +97,9 @@ TEST_F(TestProtoConvert, ProtoConvert) { fss.emplace_back("int8", FieldType::FLOAT, false); fss.emplace_back("int8", FieldType::DOUBLE, false); fss.emplace_back("int8", FieldType::STRING, true); + fss.emplace_back("int8", FieldType::POINT, false); + fss.emplace_back("int8", FieldType::LINESTRING, false); + fss.emplace_back("int8", FieldType::POLYGON, false); ::google::protobuf::RepeatedPtrField pfss, pfss2; FieldSpecConvert::FromLGraphT(fss, &pfss); UT_EXPECT_EQ(pfss.size(), fss.size()); diff --git a/test/test_type_convert.cpp b/test/test_type_convert.cpp index 89ffa34385..1d15026011 100644 --- a/test/test_type_convert.cpp +++ b/test/test_type_convert.cpp @@ -52,6 +52,6 @@ TEST_F(TestTypeConvert, TypeConvert) { UT_EXPECT_EQ(ValueToFieldData(Value::ConstRef(s), FieldType::STRING).AsString(), s); std::string point = "0101000020E6100000000000000000F03F000000000000F03F"; UT_EXPECT_TRUE(ValueToFieldData(Value::ConstRef(point), FieldType::POINT).AsWsgPoint() == - ::lgraph_api::point<::lgraph_api::Wsg84>(point)); + ::lgraph_api::Point<::lgraph_api::Wsg84>(point)); UT_EXPECT_EQ(ValueToFieldData(Value::ConstRef(point), FieldType::POINT).ToString(), point); }