Add polygons intersection function

This commit is contained in:
DoomzD 2020-06-17 18:29:08 +03:00 committed by Nikita Mikhaylov
parent d46998e114
commit 13b841f6de
2 changed files with 114 additions and 0 deletions

View File

@ -0,0 +1,112 @@
#include <Functions/FunctionFactory.h>
#include <Functions/geometryConverters.h>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <Columns/ColumnArray.h>
#include <Columns/ColumnTuple.h>
#include <Columns/ColumnsNumber.h>
#include <DataTypes/DataTypeArray.h>
#include <DataTypes/DataTypeTuple.h>
#include <DataTypes/DataTypeCustomGeo.h>
#include <memory>
namespace DB
{
namespace ErrorCodes
{
extern const int TOO_FEW_ARGUMENTS_FOR_FUNCTION;
extern const int BAD_ARGUMENTS;
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
extern const int ILLEGAL_COLUMN;
}
using CoordinateType = Float64;
using Point = boost::geometry::model::d2::point_xy<CoordinateType>;
using Polygon = boost::geometry::model::polygon<Point, false>;
using MultiPolygon = boost::geometry::model::multi_polygon<Float64Polygon>;
using Box = boost::geometry::model::box<Point>;
class FunctionPolygonsIntersection : public IFunction
{
public:
static inline const char * name = "polygonsIntersection";
explicit FunctionPolygonsIntersection() = default;
static FunctionPtr create(const Context &)
{
return std::make_shared<FunctionPolygonsIntersection>();
}
String getName() const override
{
return name;
}
bool isVariadic() const override
{
return false;
}
size_t getNumberOfArguments() const override
{
return 2;
}
DataTypePtr getReturnTypeImpl(const DataTypes &) const override
{
return DataTypeCustomMultiPolygonSerialization::nestedDataType();
}
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override
{
auto get_parser = [&block, &arguments] (size_t i) {
const ColumnWithTypeAndName polygon = block.getByPosition(arguments[i]);
return makeGeometryFromColumnParser(polygon);
};
auto first_parser = get_parser(0);
auto first_container = createContainer(first_parser);
auto second_parser = get_parser(1);
auto second_container = createContainer(second_parser);
auto res_column = ColumnArray::create(ColumnArray::create(ColumnArray::create(
ColumnTuple::create(
Columns{ColumnVector<Float64>::create(input_rows_count),
ColumnVector<Float64>::create(input_rows_count)}
)
)));
auto & data = res_column->getData();
for (size_t i = 0; i < input_rows_count; i++)
{
get(first_parser, first_container, i);
get(second_parser, second_container, i);
Float64Geometry intersection;
boost::geometry::intersection(first_container, second_container, intersection);
// GeometrySerializer<MultiPolygon, Float64MultiPolygonSerializerVisitor> serializer;
// serializer.add(intersection);
// data[i] = serializer.finalize();
}
// block.getByPosition(result).column = std::move(res_column);
}
};
void registerFunctionPolygonsIntersection(FunctionFactory & factory)
{
factory.registerFunction<FunctionPolygonsIntersection>();
}
}

View File

@ -10,6 +10,7 @@ class FunctionFactory;
void registerFunctionGeoDistance(FunctionFactory & factory);
void registerFunctionPointInEllipses(FunctionFactory & factory);
void registerFunctionPointInPolygon(FunctionFactory & factory);
// void registerFunctionPolygonsIntersection(FunctionFactory & factory);
void registerFunctionGeohashEncode(FunctionFactory & factory);
void registerFunctionGeohashDecode(FunctionFactory & factory);
void registerFunctionGeohashesInBox(FunctionFactory & factory);
@ -37,6 +38,7 @@ void registerFunctionsGeo(FunctionFactory & factory)
registerFunctionGeoDistance(factory);
registerFunctionPointInEllipses(factory);
registerFunctionPointInPolygon(factory);
// registerFunctionPolygonsIntersection(factory);
registerFunctionGeohashEncode(factory);
registerFunctionGeohashDecode(factory);
registerFunctionGeohashesInBox(factory);