mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 01:51:59 +00:00
Add other parsers
This commit is contained in:
parent
78e0db268c
commit
14a891057d
@ -5,16 +5,13 @@ namespace DB {
|
||||
|
||||
namespace {
|
||||
|
||||
size_t getArrayDepth(const ColumnWithTypeAndName & col, size_t max_depth)
|
||||
size_t getArrayDepth(DataTypePtr data_type, size_t max_depth)
|
||||
{
|
||||
size_t depth = 0;
|
||||
DataTypePtr data_type = col.type;
|
||||
|
||||
while (isArray(data_type) && depth != max_depth + 1)
|
||||
{
|
||||
data_type = static_cast<const DataTypeArray &>(*data_type).getNestedType();
|
||||
}
|
||||
|
||||
return max_depth;
|
||||
}
|
||||
|
||||
@ -22,11 +19,11 @@ size_t getArrayDepth(const ColumnWithTypeAndName & col, size_t max_depth)
|
||||
|
||||
GeometryFromColumnParser makeGeometryFromColumnParser(const ColumnWithTypeAndName & col)
|
||||
{
|
||||
switch (getArrayDepth(col, 3)) {
|
||||
switch (getArrayDepth(col.type, 3)) {
|
||||
case 0: return Float64PointFromColumnParser(*col.column);
|
||||
case 1: return Float64RingFromColumnParser(*col.column);
|
||||
// case 2: return parsePolygon(col, i);
|
||||
// case 3: return parseMultyPoligon(col, i);
|
||||
case 2: return Float64PolygonFromColumnParser(*col.column);
|
||||
case 3: return Float64MultiPolygonFromColumnParser(*col.column);
|
||||
default: throw Exception("Cannot parse geometry from column with type " + col.type->getName()
|
||||
+ ", array depth is too big", ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
|
@ -75,8 +75,7 @@ public:
|
||||
RingFromColumnParser(const IColumn & col)
|
||||
: offsets(static_cast<const ColumnArray &>(col).getOffsets())
|
||||
, pointParser(static_cast<const ColumnArray &>(col).getData())
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
RingType createContainer() const
|
||||
{
|
||||
@ -88,21 +87,103 @@ public:
|
||||
size_t l = offsets[i - 1];
|
||||
size_t r = offsets[i];
|
||||
|
||||
// reserve extra point for case when polygon is open
|
||||
container.reserve(r - l + 1);
|
||||
container.resize(r - l);
|
||||
|
||||
for (size_t j = l; j < r; j++) {
|
||||
pointParser.parse(container[j - l], l);
|
||||
pointParser.get(container[j - l], j);
|
||||
}
|
||||
|
||||
// make ring closed
|
||||
if (!boost::geometry::equals(container[0], container.back()))
|
||||
{
|
||||
container.push_back(container[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const IColumn::Offsets & offsets;
|
||||
PointParser pointParser;
|
||||
const PointParser pointParser;
|
||||
};
|
||||
|
||||
using Float64RingFromColumnParser = RingFromColumnParser<Float64Ring, Float64PointFromColumnParser>;
|
||||
|
||||
using GeometryFromColumnParser = boost::variant<Float64PointFromColumnParser, Float64RingFromColumnParser>;
|
||||
template<class PolygonType, class RingParser>
|
||||
class PolygonFromColumnParser
|
||||
{
|
||||
public:
|
||||
PolygonFromColumnParser(const IColumn & col)
|
||||
: offsets(static_cast<const ColumnArray &>(col).getOffsets())
|
||||
, ringParser(static_cast<const ColumnArray &>(col).getData())
|
||||
{}
|
||||
|
||||
PolygonType createContainer() const
|
||||
{
|
||||
return PolygonType();
|
||||
}
|
||||
|
||||
void get(PolygonType & container, size_t i) const
|
||||
{
|
||||
size_t l = offsets[i - 1];
|
||||
size_t r = offsets[i];
|
||||
|
||||
container.resize(r - l);
|
||||
ringParser.get(container.outer(), l);
|
||||
|
||||
container.inners().resize(r - l - 1);
|
||||
for (size_t j = l + 1; j < r; j++)
|
||||
{
|
||||
ringParser.get(container.inners()[j - l - 1], j);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const IColumn::Offsets & offsets;
|
||||
const RingParser ringParser;
|
||||
};
|
||||
|
||||
using Float64PolygonFromColumnParser = PolygonFromColumnParser<Float64Polygon, Float64RingFromColumnParser>;
|
||||
|
||||
template<class MultiPolygonType, class PolygonParser>
|
||||
class MultiPolygonFromColumnParser
|
||||
{
|
||||
public:
|
||||
MultiPolygonFromColumnParser(const IColumn & col)
|
||||
: offsets(static_cast<const ColumnArray &>(col).getOffsets())
|
||||
, polygonParser(static_cast<const ColumnArray &>(col).getData())
|
||||
{}
|
||||
|
||||
MultiPolygonType createContainer() const
|
||||
{
|
||||
return MultiPolygonType();
|
||||
}
|
||||
|
||||
void get(MultiPolygonType & container, size_t i) const
|
||||
{
|
||||
size_t l = offsets[i - 1];
|
||||
size_t r = offsets[i];
|
||||
|
||||
container.resize(r - l);
|
||||
for (size_t j = l; j < r; j++)
|
||||
{
|
||||
polygonParser.get(container[j - l], j - l);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const IColumn::Offsets & offsets;
|
||||
const PolygonParser polygonParser;
|
||||
};
|
||||
|
||||
using Float64MultiPolygonFromColumnParser = MultiPolygonFromColumnParser<Float64Polygon, Float64PolygonFromColumnParser>;
|
||||
|
||||
using GeometryFromColumnParser = boost::variant<
|
||||
Float64PointFromColumnParser,
|
||||
Float64RingFromColumnParser,
|
||||
Float64PolygonFromColumnParser,
|
||||
Float64MultiPolygonFromColumnParser
|
||||
>;
|
||||
|
||||
GeometryFromColumnParser makeGeometryFromColumnParser(const ColumnWithTypeAndName & col);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user