mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
add tests + improvements
This commit is contained in:
parent
adfb2885c9
commit
6a51ad425e
@ -64,13 +64,13 @@ public:
|
||||
{
|
||||
get(parser, container, i);
|
||||
|
||||
Geometry<Point> convex_hull = Polygon<Point>({{{}}});
|
||||
auto convex_hull = Polygon<Point>({{{}}});
|
||||
|
||||
boost::geometry::convex_hull(
|
||||
boost::get<MultiPolygon<Point>>(container),
|
||||
boost::get<Polygon<Point>>(convex_hull));
|
||||
convex_hull);
|
||||
|
||||
boost::get<Polygon<Point>>(convex_hull).outer().erase(
|
||||
boost::get<Polygon<Point>>(convex_hull).outer().begin());
|
||||
convex_hull.outer().erase(convex_hull.outer().begin());
|
||||
|
||||
serializer.add(convex_hull);
|
||||
}
|
||||
@ -88,14 +88,10 @@ public:
|
||||
template <>
|
||||
const char * FunctionPolygonConvexHull<CartesianPoint>::name = "polygonConvexHullCartesian";
|
||||
|
||||
// template <>
|
||||
// const char * FunctionPolygonConvexHull<GeographicPoint>::name = "polygonConvexHullGeographic";
|
||||
|
||||
|
||||
void registerFunctionPolygonConvexHull(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionPolygonConvexHull<CartesianPoint>>();
|
||||
// factory.registerFunction<FunctionPolygonConvexHull<GeographicPoint>>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -70,9 +70,13 @@ public:
|
||||
get(first_parser, first_container, i);
|
||||
get(second_parser, second_container, i);
|
||||
|
||||
Float64 distance = boost::geometry::distance(
|
||||
boost::get<MultiPolygon<Point>>(first_container),
|
||||
boost::get<MultiPolygon<Point>>(second_container));
|
||||
auto first = boost::get<MultiPolygon<Point>>(first_container);
|
||||
auto second = boost::get<MultiPolygon<Point>>(second_container);
|
||||
|
||||
boost::geometry::correct(first);
|
||||
boost::geometry::correct(second);
|
||||
|
||||
Float64 distance = boost::geometry::distance(first, second);
|
||||
|
||||
res_column->insertValue(distance);
|
||||
}
|
||||
|
@ -70,9 +70,13 @@ public:
|
||||
get(first_parser, first_container, i);
|
||||
get(second_parser, second_container, i);
|
||||
|
||||
bool equals = boost::geometry::equals(
|
||||
boost::get<MultiPolygon<Point>>(first_container),
|
||||
boost::get<MultiPolygon<Point>>(second_container));
|
||||
auto first = boost::get<MultiPolygon<Point>>(first_container);
|
||||
auto second = boost::get<MultiPolygon<Point>>(second_container);
|
||||
|
||||
boost::geometry::correct(first);
|
||||
boost::geometry::correct(second);
|
||||
|
||||
bool equals = boost::geometry::equals(first, second);
|
||||
|
||||
res_column->insertValue(equals);
|
||||
}
|
||||
|
@ -19,10 +19,12 @@
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
template <typename Point>
|
||||
class FunctionPolygonsIntersection : public IFunction
|
||||
{
|
||||
public:
|
||||
static inline const char * name = "polygonsIntersection";
|
||||
static inline const char * name;
|
||||
|
||||
explicit FunctionPolygonsIntersection() = default;
|
||||
|
||||
@ -53,28 +55,33 @@ public:
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override
|
||||
{
|
||||
auto first_parser = makeGeometryFromColumnParser<CartesianPoint>(arguments[0]);
|
||||
auto first_parser = makeGeometryFromColumnParser<Point>(arguments[0]);
|
||||
auto first_container = createContainer(first_parser);
|
||||
|
||||
auto second_parser = makeGeometryFromColumnParser<CartesianPoint>(arguments[1]);
|
||||
auto second_parser = makeGeometryFromColumnParser<Point>(arguments[1]);
|
||||
auto second_container = createContainer(second_parser);
|
||||
|
||||
MultiPolygonSerializer<CartesianPoint> serializer;
|
||||
MultiPolygonSerializer<Point> serializer;
|
||||
|
||||
/// We are not interested in some pitfalls in third-party libraries
|
||||
/// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign)
|
||||
for (size_t i = 0; i < input_rows_count; i++)
|
||||
{
|
||||
get(first_parser, first_container, i);
|
||||
get(second_parser, second_container, i);
|
||||
|
||||
CartesianGeometry intersection = CartesianMultiPolygon({{{{}}}});
|
||||
boost::geometry::intersection(
|
||||
boost::get<CartesianMultiPolygon>(first_container),
|
||||
boost::get<CartesianMultiPolygon>(second_container),
|
||||
boost::get<CartesianMultiPolygon>(intersection));
|
||||
auto intersection = MultiPolygon<Point>({{{{}}}});
|
||||
auto first = boost::get<MultiPolygon<Point>>(first_container);
|
||||
auto second = boost::get<MultiPolygon<Point>>(second_container);
|
||||
|
||||
boost::get<CartesianMultiPolygon>(intersection).erase(
|
||||
boost::get<CartesianMultiPolygon>(intersection).begin());
|
||||
/// Orient the polygons correctly.
|
||||
boost::geometry::correct(first);
|
||||
boost::geometry::correct(second);
|
||||
|
||||
/// Main work here.
|
||||
boost::geometry::intersection(first, second,intersection);
|
||||
|
||||
intersection.erase(intersection.begin());
|
||||
|
||||
serializer.add(intersection);
|
||||
}
|
||||
@ -89,9 +96,17 @@ public:
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsIntersection<CartesianPoint>::name = "polygonsIntersectionCartesian";
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsIntersection<GeographicPoint>::name = "polygonsIntersectionGeographic";
|
||||
|
||||
|
||||
void registerFunctionPolygonsIntersection(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionPolygonsIntersection>();
|
||||
factory.registerFunction<FunctionPolygonsIntersection<CartesianPoint>>();
|
||||
factory.registerFunction<FunctionPolygonsIntersection<GeographicPoint>>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -69,15 +69,17 @@ public:
|
||||
get(first_parser, first_container, i);
|
||||
get(second_parser, second_container, i);
|
||||
|
||||
Geometry<Point> sym_difference = MultiPolygon<Point>({{{{}}}});
|
||||
auto sym_difference = MultiPolygon<Point>({{{{}}}});
|
||||
|
||||
boost::geometry::sym_difference(
|
||||
boost::get<MultiPolygon<Point>>(first_container),
|
||||
boost::get<MultiPolygon<Point>>(second_container),
|
||||
boost::get<MultiPolygon<Point>>(sym_difference));
|
||||
auto first = boost::get<MultiPolygon<Point>>(first_container);
|
||||
auto second = boost::get<MultiPolygon<Point>>(second_container);
|
||||
|
||||
boost::get<MultiPolygon<Point>>(sym_difference).erase(
|
||||
boost::get<MultiPolygon<Point>>(sym_difference).begin());
|
||||
boost::geometry::correct(first);
|
||||
boost::geometry::correct(second);
|
||||
|
||||
boost::geometry::sym_difference(first, second, sym_difference);
|
||||
|
||||
sym_difference.erase(sym_difference.begin());
|
||||
|
||||
serializer.add(sym_difference);
|
||||
}
|
||||
|
@ -20,10 +20,11 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
template <typename Point>
|
||||
class FunctionPolygonsUnion : public IFunction
|
||||
{
|
||||
public:
|
||||
static inline const char * name = "polygonsUnion";
|
||||
static inline const char * name;
|
||||
|
||||
explicit FunctionPolygonsUnion() = default;
|
||||
|
||||
@ -54,29 +55,33 @@ public:
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override
|
||||
{
|
||||
auto first_parser = makeGeometryFromColumnParser<CartesianPoint>(arguments[0]);
|
||||
auto first_parser = makeGeometryFromColumnParser<Point>(arguments[0]);
|
||||
auto first_container = createContainer(first_parser);
|
||||
|
||||
auto second_parser = makeGeometryFromColumnParser<CartesianPoint>(arguments[1]);
|
||||
auto second_parser = makeGeometryFromColumnParser<Point>(arguments[1]);
|
||||
auto second_container = createContainer(second_parser);
|
||||
|
||||
MultiPolygonSerializer<CartesianPoint> serializer;
|
||||
MultiPolygonSerializer<Point> serializer;
|
||||
|
||||
/// We are not interested in some pitfalls in third-party libraries
|
||||
/// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign)
|
||||
for (size_t i = 0; i < input_rows_count; i++)
|
||||
{
|
||||
get<CartesianPoint>(first_parser, first_container, i);
|
||||
get<CartesianPoint>(second_parser, second_container, i);
|
||||
get<Point>(first_parser, first_container, i);
|
||||
get<Point>(second_parser, second_container, i);
|
||||
|
||||
Geometry<CartesianPoint> polygons_union = CartesianMultiPolygon({{{{}}}});
|
||||
/// NOLINTNEXTLINE
|
||||
boost::geometry::union_(
|
||||
boost::get<CartesianMultiPolygon>(first_container),
|
||||
boost::get<CartesianMultiPolygon>(second_container),
|
||||
boost::get<CartesianMultiPolygon>(polygons_union));
|
||||
auto first = boost::get<MultiPolygon<Point>>(first_container);
|
||||
auto second = boost::get<MultiPolygon<Point>>(second_container);
|
||||
auto polygons_union = MultiPolygon<Point>({{{{}}}});
|
||||
|
||||
boost::get<CartesianMultiPolygon>(polygons_union).erase(
|
||||
boost::get<CartesianMultiPolygon>(polygons_union).begin());
|
||||
/// Orient the polygons correctly.
|
||||
boost::geometry::correct(first);
|
||||
boost::geometry::correct(second);
|
||||
|
||||
/// Main work here.
|
||||
boost::geometry::union_(first, second, polygons_union);
|
||||
|
||||
polygons_union.erase(polygons_union.begin());
|
||||
|
||||
serializer.add(polygons_union);
|
||||
}
|
||||
@ -90,10 +95,17 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsUnion<CartesianPoint>::name = "polygonsUnionCartesian";
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsUnion<GeographicPoint>::name = "polygonsUnionGeographic";
|
||||
|
||||
|
||||
void registerFunctionPolygonsUnion(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionPolygonsUnion>();
|
||||
factory.registerFunction<FunctionPolygonsUnion<CartesianPoint>>();
|
||||
factory.registerFunction<FunctionPolygonsUnion<GeographicPoint>>();
|
||||
}
|
||||
|
||||
}
|
@ -68,12 +68,16 @@ public:
|
||||
/// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign)
|
||||
for (size_t i = 0; i < input_rows_count; i++)
|
||||
{
|
||||
get(first_parser, first_container, i);
|
||||
get(second_parser, second_container, i);
|
||||
get<Point>(first_parser, first_container, i);
|
||||
get<Point>(second_parser, second_container, i);
|
||||
|
||||
bool within = boost::geometry::within(
|
||||
boost::get<MultiPolygon<Point>>(first_container),
|
||||
boost::get<MultiPolygon<Point>>(second_container));
|
||||
auto first = boost::get<MultiPolygon<Point>>(first_container);
|
||||
auto second = boost::get<MultiPolygon<Point>>(second_container);
|
||||
|
||||
boost::geometry::correct(first);
|
||||
boost::geometry::correct(second);
|
||||
|
||||
bool within = boost::geometry::within(first, second);
|
||||
|
||||
res_column->insertValue(within);
|
||||
}
|
||||
@ -91,10 +95,14 @@ public:
|
||||
template <>
|
||||
const char * FunctionPolygonsWithin<CartesianPoint>::name = "polygonsWithinCartesian";
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsWithin<GeographicPoint>::name = "polygonsWithinGeographic";
|
||||
|
||||
|
||||
void registerFunctionPolygonsWithin(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionPolygonsWithin<CartesianPoint>>();
|
||||
factory.registerFunction<FunctionPolygonsWithin<GeographicPoint>>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,13 +65,7 @@ public:
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override
|
||||
{
|
||||
const auto * const_col = checkAndGetColumn<ColumnConst>(arguments[0].column.get());
|
||||
|
||||
auto parser = const_col ?
|
||||
makeGeometryFromColumnParser<CartesianPoint>(ColumnWithTypeAndName(const_col->getDataColumnPtr(), arguments[0].type, arguments[0].name)) :
|
||||
makeGeometryFromColumnParser<CartesianPoint>(arguments[0]);
|
||||
|
||||
bool geo_column_is_const = static_cast<bool>(const_col);
|
||||
auto parser = makeGeometryFromColumnParser<CartesianPoint>(arguments[0]);
|
||||
|
||||
auto res_column = ColumnString::create();
|
||||
auto container = createContainer(parser);
|
||||
@ -83,10 +77,8 @@ public:
|
||||
|
||||
for (size_t i = 0; i < input_rows_count; i++)
|
||||
{
|
||||
/// FIXME
|
||||
std::stringstream str; // STYLE_CHECK_ALLOW_STD_STRING_STREAM
|
||||
if (!geo_column_is_const || i == 0)
|
||||
get(parser, container, i);
|
||||
get(parser, container, i);
|
||||
|
||||
str << boost::geometry::svg(container, has_style ? style->getDataAt(i).toString() : "");
|
||||
std::string serialized = str.str();
|
||||
|
@ -45,7 +45,6 @@ public:
|
||||
|
||||
for (size_t i = 0; i < input_rows_count; i++)
|
||||
{
|
||||
/// FIXME
|
||||
std::stringstream str; // STYLE_CHECK_ALLOW_STD_STRING_STREAM
|
||||
get(parser, container, i);
|
||||
str << boost::geometry::wkt(container);
|
||||
|
@ -74,7 +74,6 @@ SRCS(
|
||||
GatherUtils/sliceFromRightConstantOffsetUnbounded.cpp
|
||||
GeoHash.cpp
|
||||
IFunction.cpp
|
||||
PolygonsUnion.cpp
|
||||
TargetSpecific.cpp
|
||||
URL/URLHierarchy.cpp
|
||||
URL/URLPathHierarchy.cpp
|
||||
@ -386,6 +385,7 @@ SRCS(
|
||||
polygonsEquals.cpp
|
||||
polygonsIntersection.cpp
|
||||
polygonsSymDifference.cpp
|
||||
polygonsUnion.cpp
|
||||
polygonsWithin.cpp
|
||||
position.cpp
|
||||
positionCaseInsensitive.cpp
|
||||
|
@ -65,7 +65,6 @@ struct Memory : boost::noncopyable, Allocator
|
||||
|
||||
size_t size() const { return m_size; }
|
||||
const char & operator[](size_t i) const { return m_data[i]; }
|
||||
/// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
|
||||
char & operator[](size_t i) { return m_data[i]; }
|
||||
const char * data() const { return m_data; }
|
||||
char * data() { return m_data; }
|
||||
|
@ -1,2 +1,4 @@
|
||||
0
|
||||
1
|
||||
0
|
||||
1
|
||||
|
@ -1,2 +1,7 @@
|
||||
select polygonsWithinCartesian([[[(0, 0),(0, 3),(1, 2.9),(2, 2.6),(2.6, 2),(2.9, 1),(3, 0),(0, 0)]]], [[[(1, 1),(1, 4),(4, 4),(4, 1),(1, 1)]]]);
|
||||
select polygonsWithinCartesian([[[(2, 2), (2, 3), (3, 3), (3, 2)]]], [[[(1, 1),(1, 4),(4, 4),(4, 1),(1, 1)]]])
|
||||
select polygonsWithinCartesian([[[(2, 2), (2, 3), (3, 3), (3, 2)]]], [[[(1, 1),(1, 4),(4, 4),(4, 1),(1, 1)]]]);
|
||||
|
||||
select polygonsWithinGeographic([[[(4.3613577, 50.8651821), (4.349556, 50.8535879), (4.3602419, 50.8435626), (4.3830299, 50.8428851), (4.3904543, 50.8564867), (4.3613148, 50.8651279)]]], [[[(4.346693, 50.858306), (4.367945, 50.852455), (4.366227, 50.840809), (4.344961, 50.833264), (4.338074, 50.848677), (4.346693, 50.858306)]]]);
|
||||
select polygonsWithinGeographic([[[(4.3501568, 50.8518269), (4.3444920, 50.8439961), (4.3565941, 50.8443213), (4.3501568, 50.8518269)]]], [[[(4.3679450, 50.8524550),(4.3466930, 50.8583060),(4.3380740, 50.8486770),(4.3449610, 50.8332640),(4.3662270, 50.8408090),(4.3679450, 50.8524550)]]]);
|
||||
|
||||
|
||||
|
@ -1 +1,2 @@
|
||||
[[[(1,2.9),(1,4),(4,4),(4,1),(2.9,1),(3,0),(0,0),(0,3),(1,2.9)]]]
|
||||
[[[(4.3666052904432435,50.84337386140151),(4.366227,50.840809),(4.344961,50.833264),(4.338074,50.848677),(4.346693,50.858306),(4.3526804582393535,50.856658100365976),(4.3613577,50.8651821),(4.3613148,50.8651279),(4.3904543,50.8564867),(4.3830299,50.8428851),(4.3666052904432435,50.84337386140151)]]]
|
||||
|
@ -1 +1,3 @@
|
||||
select polygonsUnion([[[(0, 0),(0, 3),(1, 2.9),(2, 2.6),(2.6, 2),(2.9, 1),(3, 0),(0, 0)]]], [[[(1, 1),(1, 4),(4, 4),(4, 1),(1, 1)]]])
|
||||
select polygonsUnionCartesian([[[(0, 0),(0, 3),(1, 2.9),(2, 2.6),(2.6, 2),(2.9, 1),(3, 0),(0, 0)]]], [[[(1, 1),(1, 4),(4, 4),(4, 1),(1, 1)]]]);
|
||||
|
||||
select polygonsUnionGeographic([[[(4.3613577, 50.8651821), (4.349556, 50.8535879), (4.3602419, 50.8435626), (4.3830299, 50.8428851), (4.3904543, 50.8564867), (4.3613148, 50.8651279)]]], [[[(4.346693, 50.858306), (4.367945, 50.852455), (4.366227, 50.840809), (4.344961, 50.833264), (4.338074, 50.848677), (4.346693, 50.858306)]]]);
|
||||
|
@ -1,2 +1,4 @@
|
||||
[[[(1,2.9),(2,2.6),(2.6,2),(2.9,1),(1,1),(1,2.9)]]]
|
||||
[]
|
||||
[]
|
||||
[[[(4.3666052904432435,50.84337386140151),(4.3602419,50.8435626),(4.349556,50.8535879),(4.3526804582393535,50.856658100365976),(4.367945,50.852455),(4.3666052904432435,50.84337386140151)]]]
|
||||
|
@ -1,2 +1,5 @@
|
||||
select polygonsIntersection([[[(0, 0),(0, 3),(1, 2.9),(2, 2.6),(2.6, 2),(2.9, 1),(3, 0),(0, 0)]]], [[[(1, 1),(1, 4),(4, 4),(4, 1),(1, 1)]]]);
|
||||
select polygonsIntersection([[[(0, 0),(0, 3),(1, 2.9),(2, 2.6),(2.6, 2),(2.9, 1),(3, 0),(0, 0)]]], [[[(3, 3),(3, 4),(4, 4),(4, 3),(3, 3)]]]);
|
||||
select polygonsIntersectionCartesian([[[(0, 0),(0, 3),(1, 2.9),(2, 2.6),(2.6, 2),(2.9, 1),(3, 0),(0, 0)]]], [[[(1, 1),(1, 4),(4, 4),(4, 1),(1, 1)]]]);
|
||||
select polygonsIntersectionCartesian([[[(0, 0),(0, 3),(1, 2.9),(2, 2.6),(2.6, 2),(2.9, 1),(3, 0),(0, 0)]]], [[[(3, 3),(3, 4),(4, 4),(4, 3),(3, 3)]]]);
|
||||
|
||||
select polygonsIntersectionGeographic([[[(4.346693, 50.858306), (4.367945, 50.852455), (4.366227, 50.840809), (4.344961, 50.833264), (4.338074, 50.848677), (4.346693, 50.858306)]]], [[[(25.0010, 136.9987), (17.7500, 142.5000), (11.3733, 142.5917)]]]);
|
||||
select polygonsIntersectionGeographic([[[(4.3613577, 50.8651821), (4.349556, 50.8535879), (4.3602419, 50.8435626), (4.3830299, 50.8428851), (4.3904543, 50.8564867), (4.3613148, 50.8651279)]]], [[[(4.346693, 50.858306), (4.367945, 50.852455), (4.366227, 50.840809), (4.344961, 50.833264), (4.338074, 50.848677), (4.346693, 50.858306)]]]);
|
Loading…
Reference in New Issue
Block a user