more mercator

This commit is contained in:
Nikita Mikhaylov 2021-03-03 19:47:10 +03:00
parent 9f3e0874e5
commit 7e6d1d43fe
21 changed files with 438 additions and 225 deletions

View File

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

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -335,6 +335,7 @@ SRCS(
map.cpp
match.cpp
materialize.cpp
mercatorConverters.cpp
minus.cpp
modulo.cpp
moduloOrZero.cpp

View File

@ -2,3 +2,5 @@
1
0
1
0
1

View File

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

View File

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

View File

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

View File

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

View File

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