mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
more mercator
This commit is contained in:
parent
9f3e0874e5
commit
7e6d1d43fe
@ -1,12 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/ColumnWithTypeAndName.h>
|
||||
#include <Core/Types.h>
|
||||
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
#include <boost/geometry.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnArray.h>
|
||||
#include <Columns/ColumnTuple.h>
|
||||
@ -14,12 +9,10 @@
|
||||
#include <DataTypes/DataTypeArray.h>
|
||||
#include <DataTypes/IDataType.h>
|
||||
#include <DataTypes/DataTypeCustomGeo.h>
|
||||
#include <Functions/geometryTypes.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <Interpreters/castColumn.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <common/logger_useful.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
@ -29,26 +22,6 @@ namespace ErrorCodes
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
}
|
||||
|
||||
template <typename Point>
|
||||
using Ring = boost::geometry::model::ring<Point>;
|
||||
|
||||
template <typename Point>
|
||||
using Polygon = boost::geometry::model::polygon<Point>;
|
||||
|
||||
template <typename Point>
|
||||
using MultiPolygon = boost::geometry::model::multi_polygon<Polygon<Point>>;
|
||||
|
||||
using CartesianPoint = boost::geometry::model::d2::point_xy<Float64>;
|
||||
using CartesianRing = Ring<CartesianPoint>;
|
||||
using CartesianPolygon = Polygon<CartesianPoint>;
|
||||
using CartesianMultiPolygon = MultiPolygon<CartesianPoint>;
|
||||
|
||||
/// Latitude, longitude
|
||||
using SphericalPoint = boost::geometry::model::point<Float64, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree>>;
|
||||
using SphericalRing = Ring<SphericalPoint>;
|
||||
using SphericalPolygon = Polygon<SphericalPoint>;
|
||||
using SphericalMultiPolygon = MultiPolygon<SphericalPoint>;
|
||||
|
||||
/**
|
||||
* Class which takes converts Column with type Tuple(Float64, Float64) to a vector of boost point type.
|
||||
* They are (x,y) in case of cartesian coordinated and (lon,lat) in case of Spherical.
|
||||
|
33
src/Functions/geometryTypes.h
Normal file
33
src/Functions/geometryTypes.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/Types.h>
|
||||
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
#include <boost/geometry.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
#include "common/types.h"
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
template <typename Point>
|
||||
using Ring = boost::geometry::model::ring<Point>;
|
||||
|
||||
template <typename Point>
|
||||
using Polygon = boost::geometry::model::polygon<Point>;
|
||||
|
||||
template <typename Point>
|
||||
using MultiPolygon = boost::geometry::model::multi_polygon<Polygon<Point>>;
|
||||
|
||||
using CartesianPoint = boost::geometry::model::d2::point_xy<Float64>;
|
||||
using CartesianRing = Ring<CartesianPoint>;
|
||||
using CartesianPolygon = Polygon<CartesianPoint>;
|
||||
using CartesianMultiPolygon = MultiPolygon<CartesianPoint>;
|
||||
|
||||
/// Latitude, longitude
|
||||
using SphericalPoint = boost::geometry::model::point<Float64, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree>>;
|
||||
using SphericalRing = Ring<SphericalPoint>;
|
||||
using SphericalPolygon = Polygon<SphericalPoint>;
|
||||
using SphericalMultiPolygon = MultiPolygon<SphericalPoint>;
|
||||
|
||||
}
|
111
src/Functions/mercatorConverters.cpp
Normal file
111
src/Functions/mercatorConverters.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include <Functions/mercatorConverters.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr double PI = 3.14159265358979323846;
|
||||
|
||||
constexpr double epsilon = 1e-4;
|
||||
|
||||
/// Convert angle from degrees to radians.
|
||||
double deg_to_rad(double degree) {
|
||||
return (degree - epsilon) * (PI / 180.0);
|
||||
}
|
||||
|
||||
/// Convert angle from radians to degrees.
|
||||
double rad_to_deg(double radians) {
|
||||
return radians * (180.0 / PI);
|
||||
}
|
||||
|
||||
double earth_radius_for_epsg3857 = 6378137.0;
|
||||
// constexpr double max_coordinate_epsg3857 = 20037508.34;
|
||||
|
||||
|
||||
double lon_to_x(double lon) {
|
||||
return earth_radius_for_epsg3857 * deg_to_rad(lon);
|
||||
}
|
||||
|
||||
// canonical log(tan()) version
|
||||
double lat_to_y_with_tan(double lat) { // not constexpr because math functions aren't
|
||||
return earth_radius_for_epsg3857 * std::log(std::tan(PI/4 + deg_to_rad(lat)/2));
|
||||
}
|
||||
|
||||
double x_to_lon(double x) {
|
||||
return rad_to_deg(x) / earth_radius_for_epsg3857;
|
||||
}
|
||||
|
||||
double y_to_lat(double y) { // not constexpr because math functions aren't
|
||||
return rad_to_deg(2 * std::atan(std::exp(y / earth_radius_for_epsg3857)) - PI/2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PointMercatorConverter::forward(CartesianPoint & point)
|
||||
{
|
||||
point.x(lon_to_x(point.template get<0>()));
|
||||
point.y(lat_to_y_with_tan(point.template get<1>()));
|
||||
}
|
||||
|
||||
|
||||
void RingMercatorConverter::forward(CartesianRing & ring)
|
||||
{
|
||||
for (auto & point : ring)
|
||||
PointMercatorConverter::forward(point);
|
||||
}
|
||||
|
||||
void PolygonMercatorConverter::forward(CartesianPolygon & polygon)
|
||||
{
|
||||
RingMercatorConverter::forward(polygon.outer());
|
||||
for (auto & hole : polygon.inners())
|
||||
RingMercatorConverter::forward(hole);
|
||||
}
|
||||
|
||||
void MultiPolygonMercatorConverter::forward(CartesianMultiPolygon & multipolygon)
|
||||
{
|
||||
for (auto & polygon : multipolygon)
|
||||
{
|
||||
RingMercatorConverter::forward(polygon.outer());
|
||||
for (auto & hole : polygon.inners())
|
||||
RingMercatorConverter::forward(hole);
|
||||
}
|
||||
}
|
||||
|
||||
void PointMercatorConverter::backward(CartesianPoint & point)
|
||||
{
|
||||
point.x(x_to_lon(point.template get<0>()));
|
||||
point.y(y_to_lat(point.template get<1>()));
|
||||
}
|
||||
|
||||
|
||||
void RingMercatorConverter::backward(CartesianRing & ring)
|
||||
{
|
||||
for (auto & point : ring)
|
||||
PointMercatorConverter::backward(point);
|
||||
}
|
||||
|
||||
void PolygonMercatorConverter::backward(CartesianPolygon & polygon)
|
||||
{
|
||||
RingMercatorConverter::backward(polygon.outer());
|
||||
for (auto & hole : polygon.inners())
|
||||
RingMercatorConverter::backward(hole);
|
||||
}
|
||||
|
||||
void MultiPolygonMercatorConverter::backward(CartesianMultiPolygon & multipolygon)
|
||||
{
|
||||
for (auto & polygon : multipolygon)
|
||||
{
|
||||
RingMercatorConverter::backward(polygon.outer());
|
||||
for (auto & hole : polygon.inners())
|
||||
RingMercatorConverter::backward(hole);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
85
src/Functions/mercatorConverters.h
Normal file
85
src/Functions/mercatorConverters.h
Normal file
@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include <Functions/geometryTypes.h>
|
||||
#include <Common/Exception.h>
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int LOGICAL_ERROR;
|
||||
}
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/// It must work only with CartesianPoint
|
||||
class PointMercatorConverter
|
||||
{
|
||||
public:
|
||||
static void forward(CartesianPoint & point);
|
||||
static void backward(CartesianPoint & point);
|
||||
};
|
||||
|
||||
|
||||
class RingMercatorConverter
|
||||
{
|
||||
public:
|
||||
static void forward(CartesianRing & ring);
|
||||
static void backward(CartesianRing & ring);
|
||||
};
|
||||
|
||||
|
||||
class PolygonMercatorConverter
|
||||
{
|
||||
public:
|
||||
static void forward(CartesianPolygon & polygon);
|
||||
static void backward(CartesianPolygon & polygon);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class MultiPolygonMercatorConverter
|
||||
{
|
||||
public:
|
||||
static void forward(CartesianMultiPolygon & polygon);
|
||||
static void backward(CartesianMultiPolygon & polygon);
|
||||
};
|
||||
|
||||
|
||||
struct PType
|
||||
{
|
||||
using Type = PType;
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
void mercatorForward(Geometry & geometry)
|
||||
{
|
||||
if constexpr (std::is_same_v<Geometry, CartesianPoint>)
|
||||
return PointMercatorConverter::forward(geometry);
|
||||
else if constexpr (std::is_same_v<Geometry, CartesianRing>)
|
||||
return RingMercatorConverter::forward(geometry);
|
||||
else if constexpr (std::is_same_v<Geometry, CartesianPolygon>)
|
||||
return PolygonMercatorConverter::forward(geometry);
|
||||
else if constexpr (std::is_same_v<Geometry, CartesianMultiPolygon>)
|
||||
return MultiPolygonMercatorConverter::forward(geometry);
|
||||
else
|
||||
throw Exception("Unknown geometry type", ErrorCodes::LOGICAL_ERROR);
|
||||
}
|
||||
|
||||
|
||||
template <typename Geometry>
|
||||
void mercatorBackward(Geometry & geometry)
|
||||
{
|
||||
if constexpr (std::is_same_v<Geometry, CartesianPoint>)
|
||||
return PointMercatorConverter::backward(geometry);
|
||||
else if constexpr (std::is_same_v<Geometry, CartesianRing>)
|
||||
return RingMercatorConverter::backward(geometry);
|
||||
else if constexpr (std::is_same_v<Geometry, CartesianPolygon>)
|
||||
return PolygonMercatorConverter::backward(geometry);
|
||||
else if constexpr (std::is_same_v<Geometry, CartesianMultiPolygon>)
|
||||
return MultiPolygonMercatorConverter::backward(geometry);
|
||||
else
|
||||
throw Exception("Unknown geometry type", ErrorCodes::LOGICAL_ERROR);
|
||||
}
|
||||
|
||||
}
|
@ -1,22 +1,6 @@
|
||||
#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 <common/logger_useful.h>
|
||||
|
||||
#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>
|
||||
#include <string>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
|
@ -1,22 +1,6 @@
|
||||
#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 <common/logger_useful.h>
|
||||
|
||||
#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>
|
||||
#include <string>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
|
@ -1,22 +1,6 @@
|
||||
#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 <common/logger_useful.h>
|
||||
|
||||
#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>
|
||||
#include <string>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
|
@ -1,24 +1,6 @@
|
||||
#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 <common/logger_useful.h>
|
||||
|
||||
#include <Columns/ColumnArray.h>
|
||||
#include <Columns/ColumnTuple.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypeArray.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/DataTypeCustomGeo.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
|
@ -1,24 +1,6 @@
|
||||
#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 <common/logger_useful.h>
|
||||
|
||||
#include <Columns/ColumnArray.h>
|
||||
#include <Columns/ColumnTuple.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypeArray.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/DataTypeCustomGeo.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
|
@ -1,22 +1,6 @@
|
||||
#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 <common/logger_useful.h>
|
||||
|
||||
#include <Columns/ColumnArray.h>
|
||||
#include <Columns/ColumnTuple.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <DataTypes/DataTypeArray.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/DataTypeCustomGeo.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <chrono>
|
||||
#include <Functions/mercatorConverters.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
@ -26,11 +10,29 @@ namespace ErrorCodes
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
}
|
||||
|
||||
template <typename Point>
|
||||
struct IntersectionCartesian
|
||||
{
|
||||
static inline const char * name = "polygonsIntersectionCartesian";
|
||||
using Point = CartesianPoint;
|
||||
};
|
||||
|
||||
struct IntersectionSpherical
|
||||
{
|
||||
static inline const char * name = "polygonsIntersectionSpherical";
|
||||
using Point = SphericalPoint;
|
||||
};
|
||||
|
||||
struct IntersectionMercator
|
||||
{
|
||||
static inline const char * name = "polygonsIntersectionMercator";
|
||||
using Point = CartesianPoint;
|
||||
};
|
||||
|
||||
template <typename Holder>
|
||||
class FunctionPolygonsIntersection : public IFunction
|
||||
{
|
||||
public:
|
||||
static inline const char * name;
|
||||
static inline const char * name = Holder::name;
|
||||
|
||||
explicit FunctionPolygonsIntersection() = default;
|
||||
|
||||
@ -62,6 +64,8 @@ public:
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override
|
||||
{
|
||||
using Point = typename Holder::Point;
|
||||
|
||||
MultiPolygonSerializer<Point> serializer;
|
||||
|
||||
callOnTwoGeometryDataTypes<Point>(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type)
|
||||
@ -87,10 +91,19 @@ public:
|
||||
boost::geometry::correct(first[i]);
|
||||
boost::geometry::correct(second[i]);
|
||||
|
||||
if constexpr (std::is_same_v<Holder, IntersectionMercator>)
|
||||
{
|
||||
mercatorForward(first[i]);
|
||||
mercatorForward(second[i]);
|
||||
}
|
||||
|
||||
MultiPolygon<Point> intersection{};
|
||||
/// Main work here.
|
||||
boost::geometry::intersection(first[i], second[i], intersection);
|
||||
|
||||
if constexpr (std::is_same_v<Holder, IntersectionMercator>)
|
||||
mercatorBackward(intersection);
|
||||
|
||||
serializer.add(intersection);
|
||||
}
|
||||
}
|
||||
@ -105,18 +118,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsIntersection<CartesianPoint>::name = "polygonsIntersectionCartesian";
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsIntersection<SphericalPoint>::name = "polygonsIntersectionSpherical";
|
||||
|
||||
|
||||
void registerFunctionPolygonsIntersection(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionPolygonsIntersection<CartesianPoint>>();
|
||||
factory.registerFunction<FunctionPolygonsIntersection<SphericalPoint>>();
|
||||
factory.registerFunction<FunctionPolygonsIntersection<IntersectionCartesian>>();
|
||||
factory.registerFunction<FunctionPolygonsIntersection<IntersectionSpherical>>();
|
||||
factory.registerFunction<FunctionPolygonsIntersection<IntersectionMercator>>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,21 +1,6 @@
|
||||
#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 <common/logger_useful.h>
|
||||
|
||||
#include <Columns/ColumnArray.h>
|
||||
#include <Columns/ColumnTuple.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <DataTypes/DataTypeArray.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/DataTypeCustomGeo.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <Functions/mercatorConverters.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
@ -26,11 +11,30 @@ namespace ErrorCodes
|
||||
}
|
||||
|
||||
|
||||
template <typename Point>
|
||||
struct SymDifferenceCartesian
|
||||
{
|
||||
static inline const char * name = "polygonsSymDifferenceCartesian";
|
||||
using Point = CartesianPoint;
|
||||
};
|
||||
|
||||
struct SymDifferenceSpherical
|
||||
{
|
||||
static inline const char * name = "polygonsSymDifferenceSpherical";
|
||||
using Point = SphericalPoint;
|
||||
};
|
||||
|
||||
struct SymDifferenceMercator
|
||||
{
|
||||
static inline const char * name = "polygonsSymDifferenceMercator";
|
||||
using Point = CartesianPoint;
|
||||
};
|
||||
|
||||
|
||||
template <typename Holder>
|
||||
class FunctionPolygonsSymDifference : public IFunction
|
||||
{
|
||||
public:
|
||||
static const char * name;
|
||||
static inline const char * name = Holder::name;
|
||||
|
||||
explicit FunctionPolygonsSymDifference() = default;
|
||||
|
||||
@ -61,6 +65,8 @@ public:
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override
|
||||
{
|
||||
using Point = typename Holder::Point;
|
||||
|
||||
MultiPolygonSerializer<Point> serializer;
|
||||
|
||||
callOnTwoGeometryDataTypes<Point>(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type)
|
||||
@ -84,9 +90,18 @@ public:
|
||||
boost::geometry::correct(first[i]);
|
||||
boost::geometry::correct(second[i]);
|
||||
|
||||
if constexpr (std::is_same_v<Holder, SymDifferenceMercator>)
|
||||
{
|
||||
mercatorForward(first[i]);
|
||||
mercatorForward(second[i]);
|
||||
}
|
||||
|
||||
MultiPolygon<Point> sym_difference{};
|
||||
boost::geometry::sym_difference(first[i], second[i], sym_difference);
|
||||
|
||||
if constexpr (std::is_same_v<Holder, SymDifferenceMercator>)
|
||||
mercatorBackward(sym_difference);
|
||||
|
||||
serializer.add(sym_difference);
|
||||
}
|
||||
}
|
||||
@ -101,16 +116,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsSymDifference<CartesianPoint>::name = "polygonsSymDifferenceCartesian";
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsSymDifference<SphericalPoint>::name = "polygonsSymDifferenceSpherical";
|
||||
|
||||
void registerFunctionPolygonsSymDifference(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionPolygonsSymDifference<CartesianPoint>>();
|
||||
factory.registerFunction<FunctionPolygonsSymDifference<SphericalPoint>>();
|
||||
factory.registerFunction<FunctionPolygonsSymDifference<SymDifferenceCartesian>>();
|
||||
factory.registerFunction<FunctionPolygonsSymDifference<SymDifferenceSpherical>>();
|
||||
factory.registerFunction<FunctionPolygonsSymDifference<SymDifferenceMercator>>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,21 +1,6 @@
|
||||
#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 <common/logger_useful.h>
|
||||
|
||||
#include <Columns/ColumnArray.h>
|
||||
#include <Columns/ColumnTuple.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <DataTypes/DataTypeArray.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/DataTypeCustomGeo.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <Functions/mercatorConverters.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
@ -26,11 +11,30 @@ namespace ErrorCodes
|
||||
}
|
||||
|
||||
|
||||
template <typename Point>
|
||||
struct UnionCartesian
|
||||
{
|
||||
static inline const char * name = "polygonsUnionCartesian";
|
||||
using Point = CartesianPoint;
|
||||
};
|
||||
|
||||
struct UnionSpherical
|
||||
{
|
||||
static inline const char * name = "polygonsUnionSpherical";
|
||||
using Point = SphericalPoint;
|
||||
};
|
||||
|
||||
struct UnionMercator
|
||||
{
|
||||
static inline const char * name = "polygonsUnionMercator";
|
||||
using Point = CartesianPoint;
|
||||
};
|
||||
|
||||
|
||||
template <typename Holder>
|
||||
class FunctionPolygonsUnion : public IFunction
|
||||
{
|
||||
public:
|
||||
static inline const char * name;
|
||||
static inline const char * name = Holder::name ;
|
||||
|
||||
explicit FunctionPolygonsUnion() = default;
|
||||
|
||||
@ -61,6 +65,7 @@ public:
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override
|
||||
{
|
||||
using Point = typename Holder::Point;
|
||||
MultiPolygonSerializer<Point> serializer;
|
||||
|
||||
callOnTwoGeometryDataTypes<Point>(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type)
|
||||
@ -86,10 +91,19 @@ public:
|
||||
boost::geometry::correct(first[i]);
|
||||
boost::geometry::correct(second[i]);
|
||||
|
||||
if constexpr (std::is_same_v<Holder, UnionMercator>)
|
||||
{
|
||||
mercatorForward(first[i]);
|
||||
mercatorForward(second[i]);
|
||||
}
|
||||
|
||||
MultiPolygon<Point> polygons_union{};
|
||||
/// Main work here.
|
||||
boost::geometry::union_(first[i], second[i], polygons_union);
|
||||
|
||||
if constexpr (std::is_same_v<Holder, UnionMercator>)
|
||||
mercatorBackward(polygons_union);
|
||||
|
||||
serializer.add(polygons_union);
|
||||
}
|
||||
}
|
||||
@ -104,17 +118,12 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsUnion<CartesianPoint>::name = "polygonsUnionCartesian";
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsUnion<SphericalPoint>::name = "polygonsUnionSpherical";
|
||||
|
||||
|
||||
void registerFunctionPolygonsUnion(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionPolygonsUnion<CartesianPoint>>();
|
||||
factory.registerFunction<FunctionPolygonsUnion<SphericalPoint>>();
|
||||
factory.registerFunction<FunctionPolygonsUnion<UnionCartesian>>();
|
||||
factory.registerFunction<FunctionPolygonsUnion<UnionSpherical>>();
|
||||
factory.registerFunction<FunctionPolygonsUnion<UnionMercator>>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,23 +1,6 @@
|
||||
#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 <common/logger_useful.h>
|
||||
|
||||
#include <Columns/ColumnArray.h>
|
||||
#include <Columns/ColumnTuple.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypeArray.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/DataTypeCustomGeo.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <Functions/mercatorConverters.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
@ -27,12 +10,29 @@ namespace ErrorCodes
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
}
|
||||
|
||||
struct WithinCartesian
|
||||
{
|
||||
static inline const char * name = "polygonsWithinCartesian";
|
||||
using Point = CartesianPoint;
|
||||
};
|
||||
|
||||
template <typename Point>
|
||||
struct WithinSpherical
|
||||
{
|
||||
static inline const char * name = "polygonsWithinSpherical";
|
||||
using Point = SphericalPoint;
|
||||
};
|
||||
|
||||
struct WithinMercator
|
||||
{
|
||||
static inline const char * name = "polygonsWithinMercator";
|
||||
using Point = CartesianPoint;
|
||||
};
|
||||
|
||||
template <typename Holder>
|
||||
class FunctionPolygonsWithin : public IFunction
|
||||
{
|
||||
public:
|
||||
static inline const char * name;
|
||||
static inline const char * name = Holder::name;
|
||||
|
||||
explicit FunctionPolygonsWithin() = default;
|
||||
|
||||
@ -63,6 +63,7 @@ public:
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override
|
||||
{
|
||||
using Point = typename Holder::Point;
|
||||
auto res_column = ColumnUInt8::create();
|
||||
auto & res_data = res_column->getData();
|
||||
res_data.reserve(input_rows_count);
|
||||
@ -88,6 +89,12 @@ public:
|
||||
boost::geometry::correct(first[i]);
|
||||
boost::geometry::correct(second[i]);
|
||||
|
||||
if constexpr (std::is_same_v<Holder, WithinMercator>)
|
||||
{
|
||||
mercatorForward(first[i]);
|
||||
mercatorForward(second[i]);
|
||||
}
|
||||
|
||||
res_data.emplace_back(boost::geometry::within(first[i], second[i]));
|
||||
}
|
||||
}
|
||||
@ -102,18 +109,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsWithin<CartesianPoint>::name = "polygonsWithinCartesian";
|
||||
|
||||
template <>
|
||||
const char * FunctionPolygonsWithin<SphericalPoint>::name = "polygonsWithinSpherical";
|
||||
|
||||
|
||||
void registerFunctionPolygonsWithin(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionPolygonsWithin<CartesianPoint>>();
|
||||
factory.registerFunction<FunctionPolygonsWithin<SphericalPoint>>();
|
||||
factory.registerFunction<FunctionPolygonsWithin<WithinCartesian>>();
|
||||
factory.registerFunction<FunctionPolygonsWithin<WithinSpherical>>();
|
||||
factory.registerFunction<FunctionPolygonsWithin<WithinMercator>>();
|
||||
}
|
||||
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -335,6 +335,7 @@ SRCS(
|
||||
map.cpp
|
||||
match.cpp
|
||||
materialize.cpp
|
||||
mercatorConverters.cpp
|
||||
minus.cpp
|
||||
modulo.cpp
|
||||
moduloOrZero.cpp
|
||||
|
@ -2,3 +2,5 @@
|
||||
1
|
||||
0
|
||||
1
|
||||
0
|
||||
1
|
||||
|
@ -4,4 +4,5 @@ select polygonsWithinCartesian([[[(2., 2.), (2., 3.), (3., 3.), (3., 2.)]]], [[[
|
||||
select polygonsWithinSpherical([[[(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 polygonsWithinSpherical([[[(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)]]]);
|
||||
|
||||
|
||||
select polygonsWithinMercator([[[(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 polygonsWithinMercator([[[(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,2 +1,7 @@
|
||||
--------
|
||||
[[[(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)]]]
|
||||
--------
|
||||
[[[(4.366505261795747,50.843273415405),(4.3661270000000005,50.840709),(4.344861,50.83316399999998),(4.337974,50.84857699999999),(4.346593,50.858205999999996),(4.352580404040105,50.85655765067624),(4.3612577,50.86508209999998),(4.361214800000001,50.8650279),(4.3903543,50.85638669999999),(4.382929900000001,50.842785099999986),(4.366505261795747,50.843273415405)]]]
|
||||
|
@ -1,5 +1,11 @@
|
||||
select '--------';
|
||||
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 '--------';
|
||||
SELECT polygonsUnionCartesian([[[(2., 100.0000991821289), (0., 3.), (1., 2.9), (2., 2.6), (2.6, 2.), (2.9, 1), (3., 0.), (100.0000991821289, 2.)]]], [[[(1., 1.), (1000.0001220703125, nan), (4., 4.), (4., 1.), (1., 1.)]]]); -- { serverError 43 }
|
||||
|
||||
select '--------';
|
||||
select polygonsUnionSpherical([[[(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 '--------';
|
||||
select polygonsUnionMercator([[[(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,4 +1,9 @@
|
||||
--------
|
||||
[[[(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)]]]
|
||||
--------
|
||||
[]
|
||||
[[[(4.366505261795747,50.843273415405),(4.3601419,50.8434626),(4.349456,50.8534879),(4.352580404040105,50.85655765067624),(4.367845,50.85235499999999),(4.366505261795747,50.843273415405)]]]
|
||||
|
@ -1,5 +1,12 @@
|
||||
|
||||
select '--------';
|
||||
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 '--------';
|
||||
select polygonsIntersectionSpherical([[[(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 polygonsIntersectionSpherical([[[(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 '--------';
|
||||
select polygonsIntersectionMercator([[[(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 polygonsIntersectionMercator([[[(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