add tests + improvements

This commit is contained in:
Nikita Mikhailov 2021-01-21 15:31:47 +03:00 committed by Nikita Mikhaylov
parent adfb2885c9
commit 6a51ad425e
17 changed files with 116 additions and 70 deletions

View File

@ -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>>();
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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>>();
}
}

View File

@ -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);
}

View File

@ -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>>();
}
}

View File

@ -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>>();
}
}

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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; }

View File

@ -1,2 +1,4 @@
0
1
0
1

View File

@ -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)]]]);

View File

@ -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)]]]

View File

@ -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)]]]);

View File

@ -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)]]]

View File

@ -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)]]]);