mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-25 09:02:00 +00:00
Added support for reading multilinestring wkts
This commit is contained in:
parent
f9179986d1
commit
a80c7c080c
@ -52,6 +52,48 @@ Result:
|
|||||||
└───────────────────────────────┴───────────────┘
|
└───────────────────────────────┴───────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## LineString
|
||||||
|
|
||||||
|
`LineString` is a line stored as an array of points: [Array](array.md)([Point](#point)).
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
Query:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE geo_linestring (l LineString) ENGINE = Memory();
|
||||||
|
INSERT INTO geo_linestring VALUES([(0, 0), (10, 0), (10, 10), (0, 10)]);
|
||||||
|
SELECT l, toTypeName(l) FROM geo_linestring;
|
||||||
|
```
|
||||||
|
Result:
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─r─────────────────────────────┬─toTypeName(r)─┐
|
||||||
|
│ [(0,0),(10,0),(10,10),(0,10)] │ LineString │
|
||||||
|
└───────────────────────────────┴───────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## MultiLineString
|
||||||
|
|
||||||
|
`MultiLineString` is multiple lines stored as an array of `LineString`: [Array](array.md)([LineString](#linestring)).
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
Query:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE geo_multilinestring (l MultiLineString) ENGINE = Memory();
|
||||||
|
INSERT INTO geo_multilinestring VALUES([[(0, 0), (10, 0), (10, 10), (0, 10)], [(1, 1), (2, 2), (3, 3)]]);
|
||||||
|
SELECT l, toTypeName(l) FROM geo_multilinestring;
|
||||||
|
```
|
||||||
|
Result:
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─l───────────────────────────────────────────────────┬─toTypeName(l)───┐
|
||||||
|
│ [[(0,0),(10,0),(10,10),(0,10)],[(1,1),(2,2),(3,3)]] │ MultiLineString │
|
||||||
|
└─────────────────────────────────────────────────────┴─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
## Polygon
|
## Polygon
|
||||||
|
|
||||||
`Polygon` is a polygon with holes stored as an array of rings: [Array](array.md)([Ring](#ring)). First element of outer array is the outer shape of polygon and all the following elements are holes.
|
`Polygon` is a polygon with holes stored as an array of rings: [Array](array.md)([Ring](#ring)). First element of outer array is the outer shape of polygon and all the following elements are holes.
|
||||||
|
@ -11,6 +11,8 @@ Returns a WKT (Well Known Text) geometric object from various [Geo Data Types](.
|
|||||||
- POINT
|
- POINT
|
||||||
- POLYGON
|
- POLYGON
|
||||||
- MULTIPOLYGON
|
- MULTIPOLYGON
|
||||||
|
- LINESTRING
|
||||||
|
- MULTILINESTRING
|
||||||
|
|
||||||
**Syntax**
|
**Syntax**
|
||||||
|
|
||||||
@ -26,12 +28,16 @@ WKT(geo_data)
|
|||||||
- [Ring](../../data-types/geo.md#ring)
|
- [Ring](../../data-types/geo.md#ring)
|
||||||
- [Polygon](../../data-types/geo.md#polygon)
|
- [Polygon](../../data-types/geo.md#polygon)
|
||||||
- [MultiPolygon](../../data-types/geo.md#multipolygon)
|
- [MultiPolygon](../../data-types/geo.md#multipolygon)
|
||||||
|
- [LineString](../../data-types/geo.md#linestring)
|
||||||
|
- [MultiLineString](../../data-types/geo.md#multilinestring)
|
||||||
|
|
||||||
**Returned value**
|
**Returned value**
|
||||||
|
|
||||||
- WKT geometric object `POINT` is returned for a Point.
|
- WKT geometric object `POINT` is returned for a Point.
|
||||||
- WKT geometric object `POLYGON` is returned for a Polygon
|
- WKT geometric object `POLYGON` is returned for a Polygon
|
||||||
- WKT geometric object `MULTIPOLYGON` is returned for a MultiPolygon.
|
- WKT geometric object `MULTIPOLYGON` is returned for a MultiPolygon.
|
||||||
|
- WKT geometric object `LINESTRING` is returned for a LineString.
|
||||||
|
- WKT geometric object `MULTILINESTRING` is returned for a MultiLineString.
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
@ -170,6 +176,34 @@ SELECT readWKTLineString('LINESTRING (1 1, 2 2, 3 3, 1 1)');
|
|||||||
[(1,1),(2,2),(3,3),(1,1)]
|
[(1,1),(2,2),(3,3),(1,1)]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## readWKTMultiLineString
|
||||||
|
|
||||||
|
Parses a Well-Known Text (WKT) representation of a MultiLineString geometry and returns it in the internal ClickHouse format.
|
||||||
|
|
||||||
|
### Syntax
|
||||||
|
|
||||||
|
```sql
|
||||||
|
readWKTMultiLineString(wkt_string)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
- `wkt_string`: The input WKT string representing a MultiLineString geometry.
|
||||||
|
|
||||||
|
### Returned value
|
||||||
|
|
||||||
|
The function returns a ClickHouse internal representation of the multilinestring geometry.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT wkt(readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3), (4 4, 5 5, 6 6))'));
|
||||||
|
```
|
||||||
|
|
||||||
|
```response
|
||||||
|
[[(1,1),(2,2),(3,3)],[(4,4),(5,5),(6,6)]]
|
||||||
|
```
|
||||||
|
|
||||||
## readWKTRing
|
## readWKTRing
|
||||||
|
|
||||||
Parses a Well-Known Text (WKT) representation of a Polygon geometry and returns a ring (closed linestring) in the internal ClickHouse format.
|
Parses a Well-Known Text (WKT) representation of a Polygon geometry and returns a ring (closed linestring) in the internal ClickHouse format.
|
||||||
|
@ -24,6 +24,13 @@ void registerDataTypeDomainGeo(DataTypeFactory & factory)
|
|||||||
std::make_unique<DataTypeCustomDesc>(std::make_unique<DataTypeLineStringName>()));
|
std::make_unique<DataTypeCustomDesc>(std::make_unique<DataTypeLineStringName>()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Custom type for mulitple lines stored as Array(LineString)
|
||||||
|
factory.registerSimpleDataTypeCustom("MultiLineString", []
|
||||||
|
{
|
||||||
|
return std::make_pair(DataTypeFactory::instance().get("Array(LineString)"),
|
||||||
|
std::make_unique<DataTypeCustomDesc>(std::make_unique<DataTypeMultiLineStringName>()));
|
||||||
|
});
|
||||||
|
|
||||||
// Custom type for simple polygon without holes stored as Array(Point)
|
// Custom type for simple polygon without holes stored as Array(Point)
|
||||||
factory.registerSimpleDataTypeCustom("Ring", []
|
factory.registerSimpleDataTypeCustom("Ring", []
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,12 @@ public:
|
|||||||
DataTypeLineStringName() : DataTypeCustomFixedName("LineString") {}
|
DataTypeLineStringName() : DataTypeCustomFixedName("LineString") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DataTypeMultiLineStringName : public DataTypeCustomFixedName
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DataTypeMultiLineStringName() : DataTypeCustomFixedName("MultiLineString") {}
|
||||||
|
};
|
||||||
|
|
||||||
class DataTypeRingName : public DataTypeCustomFixedName
|
class DataTypeRingName : public DataTypeCustomFixedName
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -31,6 +31,9 @@ namespace ErrorCodes
|
|||||||
template <typename Point>
|
template <typename Point>
|
||||||
using LineString = boost::geometry::model::linestring<Point>;
|
using LineString = boost::geometry::model::linestring<Point>;
|
||||||
|
|
||||||
|
template <typename Point>
|
||||||
|
using MultiLineString = boost::geometry::model::multi_linestring<LineString<Point>>;
|
||||||
|
|
||||||
template <typename Point>
|
template <typename Point>
|
||||||
using Ring = boost::geometry::model::ring<Point>;
|
using Ring = boost::geometry::model::ring<Point>;
|
||||||
|
|
||||||
@ -42,12 +45,14 @@ using MultiPolygon = boost::geometry::model::multi_polygon<Polygon<Point>>;
|
|||||||
|
|
||||||
using CartesianPoint = boost::geometry::model::d2::point_xy<Float64>;
|
using CartesianPoint = boost::geometry::model::d2::point_xy<Float64>;
|
||||||
using CartesianLineString = LineString<CartesianPoint>;
|
using CartesianLineString = LineString<CartesianPoint>;
|
||||||
|
using CartesianMultiLineString = MultiLineString<CartesianPoint>;
|
||||||
using CartesianRing = Ring<CartesianPoint>;
|
using CartesianRing = Ring<CartesianPoint>;
|
||||||
using CartesianPolygon = Polygon<CartesianPoint>;
|
using CartesianPolygon = Polygon<CartesianPoint>;
|
||||||
using CartesianMultiPolygon = MultiPolygon<CartesianPoint>;
|
using CartesianMultiPolygon = MultiPolygon<CartesianPoint>;
|
||||||
|
|
||||||
using SphericalPoint = boost::geometry::model::point<Float64, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree>>;
|
using SphericalPoint = boost::geometry::model::point<Float64, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree>>;
|
||||||
using SphericalLineString = LineString<SphericalPoint>;
|
using SphericalLineString = LineString<SphericalPoint>;
|
||||||
|
using SphericalMultiLineString = MultiLineString<SphericalPoint>;
|
||||||
using SphericalRing = Ring<SphericalPoint>;
|
using SphericalRing = Ring<SphericalPoint>;
|
||||||
using SphericalPolygon = Polygon<SphericalPoint>;
|
using SphericalPolygon = Polygon<SphericalPoint>;
|
||||||
using SphericalMultiPolygon = MultiPolygon<SphericalPoint>;
|
using SphericalMultiPolygon = MultiPolygon<SphericalPoint>;
|
||||||
@ -113,6 +118,28 @@ struct ColumnToLineStringsConverter
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class which converts Column with type Array(Array(Tuple(Float64, Float64))) to a vector of boost multi_linestring type.
|
||||||
|
*/
|
||||||
|
template <typename Point>
|
||||||
|
struct ColumnToMultiLineStringsConverter
|
||||||
|
{
|
||||||
|
static std::vector<MultiLineString<Point>> convert(ColumnPtr col)
|
||||||
|
{
|
||||||
|
const IColumn::Offsets & offsets = typeid_cast<const ColumnArray &>(*col).getOffsets();
|
||||||
|
size_t prev_offset = 0;
|
||||||
|
std::vector<MultiLineString<Point>> answer(offsets.size());
|
||||||
|
auto all_linestrings = ColumnToLineStringsConverter<Point>::convert(typeid_cast<const ColumnArray &>(*col).getDataPtr());
|
||||||
|
for (size_t iter = 0; iter < offsets.size() && iter < all_linestrings.size(); ++iter)
|
||||||
|
{
|
||||||
|
for (size_t linestring_iter = prev_offset; linestring_iter < offsets[iter]; ++linestring_iter)
|
||||||
|
answer[iter].emplace_back(std::move(all_linestrings[linestring_iter]));
|
||||||
|
prev_offset = offsets[iter];
|
||||||
|
}
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class which converts Column with type Array(Tuple(Float64, Float64)) to a vector of boost ring type.
|
* Class which converts Column with type Array(Tuple(Float64, Float64)) to a vector of boost ring type.
|
||||||
*/
|
*/
|
||||||
@ -268,6 +295,38 @@ private:
|
|||||||
ColumnUInt64::MutablePtr offsets;
|
ColumnUInt64::MutablePtr offsets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Serialize Point, MultiLineString as MultiLineString
|
||||||
|
template <typename Point>
|
||||||
|
class MultiLineStringSerializer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MultiLineStringSerializer()
|
||||||
|
: offsets(ColumnUInt64::create())
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit MultiLineStringSerializer(size_t n)
|
||||||
|
: offsets(ColumnUInt64::create(n))
|
||||||
|
{}
|
||||||
|
|
||||||
|
void add(const MultiLineString<Point> & multilinestring)
|
||||||
|
{
|
||||||
|
size += multilinestring.size();
|
||||||
|
offsets->insertValue(size);
|
||||||
|
for (const auto & linestring : multilinestring)
|
||||||
|
linestring_serializer.add(linestring);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnPtr finalize()
|
||||||
|
{
|
||||||
|
return ColumnArray::create(linestring_serializer.finalize(), std::move(offsets));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t size = 0;
|
||||||
|
LineStringSerializer<Point> linestring_serializer;
|
||||||
|
ColumnUInt64::MutablePtr offsets;
|
||||||
|
};
|
||||||
|
|
||||||
/// Almost the same as LineStringSerializer
|
/// Almost the same as LineStringSerializer
|
||||||
/// Serialize Point, Ring as Ring
|
/// Serialize Point, Ring as Ring
|
||||||
template <typename Point>
|
template <typename Point>
|
||||||
@ -411,6 +470,11 @@ static void callOnGeometryDataType(DataTypePtr type, F && f)
|
|||||||
else if (factory.get("LineString")->equals(*type) && type->getCustomName() && type->getCustomName()->getName() == "LineString")
|
else if (factory.get("LineString")->equals(*type) && type->getCustomName() && type->getCustomName()->getName() == "LineString")
|
||||||
return f(ConverterType<ColumnToLineStringsConverter<Point>>());
|
return f(ConverterType<ColumnToLineStringsConverter<Point>>());
|
||||||
|
|
||||||
|
/// We should take the name into consideration to avoid ambiguity.
|
||||||
|
/// Because for example both MultiLineString and Polygon are resolved to Array(Tuple(Point)).
|
||||||
|
else if (factory.get("MultiLineString")->equals(*type) && type->getCustomName() && type->getCustomName()->getName() == "MultiLineString")
|
||||||
|
return f(ConverterType<ColumnToMultiLineStringsConverter<Point>>());
|
||||||
|
|
||||||
/// For backward compatibility if we call this function not on a custom type, we will consider Array(Tuple(Point)) as type Ring.
|
/// For backward compatibility if we call this function not on a custom type, we will consider Array(Tuple(Point)) as type Ring.
|
||||||
else if (factory.get("Ring")->equals(*type))
|
else if (factory.get("Ring")->equals(*type))
|
||||||
return f(ConverterType<ColumnToRingsConverter<Point>>());
|
return f(ConverterType<ColumnToRingsConverter<Point>>());
|
||||||
|
@ -75,6 +75,8 @@ public:
|
|||||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be Point", getName());
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be Point", getName());
|
||||||
else if constexpr (std::is_same_v<ColumnToLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToLineStringsConverter<Point>, RightConverter>)
|
else if constexpr (std::is_same_v<ColumnToLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToLineStringsConverter<Point>, RightConverter>)
|
||||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be LineString", getName());
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be LineString", getName());
|
||||||
|
else if constexpr (std::is_same_v<ColumnToMultiLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToMultiLineStringsConverter<Point>, RightConverter>)
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be MultiLineString", getName());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst());
|
auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst());
|
||||||
|
@ -73,6 +73,8 @@ public:
|
|||||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be Point", getName());
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be Point", getName());
|
||||||
else if constexpr (std::is_same_v<ColumnToLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToLineStringsConverter<Point>, RightConverter>)
|
else if constexpr (std::is_same_v<ColumnToLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToLineStringsConverter<Point>, RightConverter>)
|
||||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be LineString", getName());
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be LineString", getName());
|
||||||
|
else if constexpr (std::is_same_v<ColumnToMultiLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToMultiLineStringsConverter<Point>, RightConverter>)
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be MultiLineString", getName());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst());
|
auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst());
|
||||||
|
@ -73,6 +73,8 @@ public:
|
|||||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be Point", getName());
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be Point", getName());
|
||||||
else if constexpr (std::is_same_v<ColumnToLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToLineStringsConverter<Point>, RightConverter>)
|
else if constexpr (std::is_same_v<ColumnToLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToLineStringsConverter<Point>, RightConverter>)
|
||||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be LineString", getName());
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be LineString", getName());
|
||||||
|
else if constexpr (std::is_same_v<ColumnToMultiLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToMultiLineStringsConverter<Point>, RightConverter>)
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be MultiLineString", getName());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst());
|
auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst());
|
||||||
|
@ -77,6 +77,8 @@ public:
|
|||||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be Point", getName());
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be Point", getName());
|
||||||
else if constexpr (std::is_same_v<ColumnToLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToLineStringsConverter<Point>, RightConverter>)
|
else if constexpr (std::is_same_v<ColumnToLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToLineStringsConverter<Point>, RightConverter>)
|
||||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be LineString", getName());
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be LineString", getName());
|
||||||
|
else if constexpr (std::is_same_v<ColumnToMultiLineStringsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToMultiLineStringsConverter<Point>, RightConverter>)
|
||||||
|
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be MultiLineString", getName());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst());
|
auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst());
|
||||||
|
@ -87,6 +87,11 @@ struct ReadWKTLineStringNameHolder
|
|||||||
static constexpr const char * name = "readWKTLineString";
|
static constexpr const char * name = "readWKTLineString";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ReadWKTMultiLineStringNameHolder
|
||||||
|
{
|
||||||
|
static constexpr const char * name = "readWKTMultiLineString";
|
||||||
|
};
|
||||||
|
|
||||||
struct ReadWKTRingNameHolder
|
struct ReadWKTRingNameHolder
|
||||||
{
|
{
|
||||||
static constexpr const char * name = "readWKTRing";
|
static constexpr const char * name = "readWKTRing";
|
||||||
@ -131,6 +136,31 @@ Parses a Well-Known Text (WKT) representation of a LineString geometry and retur
|
|||||||
},
|
},
|
||||||
.categories{"Unique identifiers"}
|
.categories{"Unique identifiers"}
|
||||||
});
|
});
|
||||||
|
factory.registerFunction<FunctionReadWKT<DataTypeMultiLineStringName, CartesianMultiLineString, MultiLineStringSerializer<CartesianPoint>, ReadWKTMultiLineStringNameHolder>>(FunctionDocumentation
|
||||||
|
{
|
||||||
|
.description=R"(
|
||||||
|
Parses a Well-Known Text (WKT) representation of a MultiLineString geometry and returns it in the internal ClickHouse format.
|
||||||
|
)",
|
||||||
|
.syntax = "readWKTMultiLineString(wkt_string)",
|
||||||
|
.arguments{
|
||||||
|
{"wkt_string", "The input WKT string representing a MultiLineString geometry."}
|
||||||
|
},
|
||||||
|
.returned_value = "The function returns a ClickHouse internal representation of the multilinestring geometry.",
|
||||||
|
.examples{
|
||||||
|
{"first call", "SELECT readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3), (4 4, 5 5, 6 6))');", R"(
|
||||||
|
┌─readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3), (4 4, 5 5, 6 6))')─┐
|
||||||
|
│ [[(1,1),(2,2),(3,3)],[(4,4),(5,5),(6,6)]] │
|
||||||
|
└──────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
)"},
|
||||||
|
{"second call", "SELECT toTypeName(readWKTLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1))'));", R"(
|
||||||
|
┌─toTypeName(readWKTLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1))'))─┐
|
||||||
|
│ MultiLineString │
|
||||||
|
└─────────────────────────────────────────────────────────────────────────┘
|
||||||
|
)"},
|
||||||
|
},
|
||||||
|
.categories{"Unique identifiers"}
|
||||||
|
});
|
||||||
factory.registerFunction<FunctionReadWKT<DataTypeRingName, CartesianRing, RingSerializer<CartesianPoint>, ReadWKTRingNameHolder>>();
|
factory.registerFunction<FunctionReadWKT<DataTypeRingName, CartesianRing, RingSerializer<CartesianPoint>, ReadWKTRingNameHolder>>();
|
||||||
factory.registerFunction<FunctionReadWKT<DataTypePolygonName, CartesianPolygon, PolygonSerializer<CartesianPoint>, ReadWKTPolygonNameHolder>>();
|
factory.registerFunction<FunctionReadWKT<DataTypePolygonName, CartesianPolygon, PolygonSerializer<CartesianPoint>, ReadWKTPolygonNameHolder>>();
|
||||||
factory.registerFunction<FunctionReadWKT<DataTypeMultiPolygonName, CartesianMultiPolygon, MultiPolygonSerializer<CartesianPoint>, ReadWKTMultiPolygonNameHolder>>();
|
factory.registerFunction<FunctionReadWKT<DataTypeMultiPolygonName, CartesianMultiPolygon, MultiPolygonSerializer<CartesianPoint>, ReadWKTMultiPolygonNameHolder>>();
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
-- { echoOn }
|
||||||
|
SELECT readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1))');
|
||||||
|
[[(1,1),(2,2),(3,3),(1,1)]]
|
||||||
|
SELECT toTypeName(readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1))'));
|
||||||
|
MultiLineString
|
||||||
|
SELECT wkt(readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1))'));
|
||||||
|
MULTILINESTRING((1 1,2 2,3 3,1 1))
|
||||||
|
SELECT readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1), (1 0, 2 0, 3 0))');
|
||||||
|
[[(1,1),(2,2),(3,3),(1,1)],[(1,0),(2,0),(3,0)]]
|
||||||
|
SELECT toTypeName(readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1), (1 0, 2 0, 3 0))'));
|
||||||
|
MultiLineString
|
||||||
|
SELECT wkt(readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1), (1 0, 2 0, 3 0))'));
|
||||||
|
MULTILINESTRING((1 1,2 2,3 3,1 1),(1 0,2 0,3 0))
|
||||||
|
-- Native Array(Array(Tuple(Float64, Float64))) is treated as Polygon, not as MultiLineString.
|
||||||
|
WITH wkt(CAST([[(1, 1), (2, 2), (3, 3), (1, 1)]], 'Array(Array(Tuple(Float64, Float64)))')) as x
|
||||||
|
SELECT x, toTypeName(x), readWKTPolygon(x) as y, toTypeName(y);
|
||||||
|
POLYGON((1 1,2 2,3 3,1 1)) String [[(1,1),(2,2),(3,3),(1,1)]] Polygon
|
12
tests/queries/0_stateless/03215_multilinestring_geometry.sql
Normal file
12
tests/queries/0_stateless/03215_multilinestring_geometry.sql
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
-- { echoOn }
|
||||||
|
SELECT readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1))');
|
||||||
|
SELECT toTypeName(readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1))'));
|
||||||
|
SELECT wkt(readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1))'));
|
||||||
|
|
||||||
|
SELECT readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1), (1 0, 2 0, 3 0))');
|
||||||
|
SELECT toTypeName(readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1), (1 0, 2 0, 3 0))'));
|
||||||
|
SELECT wkt(readWKTMultiLineString('MULTILINESTRING ((1 1, 2 2, 3 3, 1 1), (1 0, 2 0, 3 0))'));
|
||||||
|
|
||||||
|
-- Native Array(Array(Tuple(Float64, Float64))) is treated as Polygon, not as MultiLineString.
|
||||||
|
WITH wkt(CAST([[(1, 1), (2, 2), (3, 3), (1, 1)]], 'Array(Array(Tuple(Float64, Float64)))')) as x
|
||||||
|
SELECT x, toTypeName(x), readWKTPolygon(x) as y, toTypeName(y);
|
@ -561,6 +561,7 @@ MindsDB
|
|||||||
Mongodb
|
Mongodb
|
||||||
Monotonicity
|
Monotonicity
|
||||||
MsgPack
|
MsgPack
|
||||||
|
MultiLineString
|
||||||
MultiPolygon
|
MultiPolygon
|
||||||
Multiline
|
Multiline
|
||||||
Multiqueries
|
Multiqueries
|
||||||
@ -2361,6 +2362,7 @@ rankCorr
|
|||||||
rapidjson
|
rapidjson
|
||||||
rawblob
|
rawblob
|
||||||
readWKTLineString
|
readWKTLineString
|
||||||
|
readWKTMultiLineString
|
||||||
readWKTMultiPolygon
|
readWKTMultiPolygon
|
||||||
readWKTPoint
|
readWKTPoint
|
||||||
readWKTPolygon
|
readWKTPolygon
|
||||||
|
Loading…
Reference in New Issue
Block a user