diff --git a/entwine/reader/query-params.hpp b/entwine/reader/query-params.hpp index 2aae8c16..07124bdf 100644 --- a/entwine/reader/query-params.hpp +++ b/entwine/reader/query-params.hpp @@ -11,11 +11,13 @@ #pragma once #include +#include #include #include #include +#include namespace entwine { @@ -89,6 +91,16 @@ class QueryParams throw std::runtime_error("Invalid depth specification"); } } + + if (q.isMember("nativeBounds")) + { + if (q.isMember("bounds")) + { + throw std::runtime_error("Cannot specify multiple bounds"); + } + + m_nativeBounds = std::make_shared(q["nativeBounds"]); + } } const Bounds& bounds() const { return m_bounds; } @@ -97,12 +109,16 @@ class QueryParams std::size_t de() const { return m_depthEnd; } const Json::Value& filter() const { return m_filter; } + const Bounds* nativeBounds() const { return m_nativeBounds.get(); } + private: const Bounds m_bounds; const Delta m_delta; const std::size_t m_depthBegin; const std::size_t m_depthEnd; const Json::Value m_filter; + + std::shared_ptr m_nativeBounds; }; } // namespace entwine diff --git a/entwine/reader/query.cpp b/entwine/reader/query.cpp index bb9b2bdd..18b6e7e7 100644 --- a/entwine/reader/query.cpp +++ b/entwine/reader/query.cpp @@ -83,10 +83,17 @@ Bounds Query::localize(const Bounds& q, const Delta& localDelta) const Query::Query(const Reader& reader, const QueryParams& p) : m_reader(reader) + , m_params(p) , m_metadata(m_reader.metadata()) , m_structure(m_metadata.structure()) - , m_delta(localize(p.delta())) - , m_bounds(localize(p.bounds(), m_delta)) + , m_delta( + p.nativeBounds() ? + p.delta() : + localize(p.delta())) + , m_bounds( + p.nativeBounds() ? + localize(*p.nativeBounds(), m_metadata.delta()->inverse()) : + localize(p.bounds(), m_delta)) , m_depthBegin(p.db()) , m_depthEnd(p.de() ? p.de() : std::numeric_limits::max()) , m_filter(m_reader.metadata(), m_bounds, p.filter(), &m_delta) @@ -265,7 +272,10 @@ ReadQuery::ReadQuery( : Query(reader, params) , m_schema(schema.empty() ? m_metadata.schema() : schema) , m_reg(reader, m_schema) - , m_mid(m_metadata.boundsScaledCubic().mid()) + , m_mid( + params.nativeBounds() ? + m_delta.offset() : + m_metadata.boundsScaledCubic().mid()) { } void ReadQuery::chunk(const ChunkReader& cr) @@ -293,7 +303,7 @@ void ReadQuery::process(const PointInfo& info) { const DimInfo& dimInfo(dim.info()); dimNum = pdal::Utils::toNative(dimInfo.id()) - 1; - if (m_delta.exists() && dimNum < 3) + if ((m_delta.exists() || m_params.nativeBounds()) && dimNum < 3) { setScaled(dimInfo, dimNum, pos); } diff --git a/entwine/reader/query.hpp b/entwine/reader/query.hpp index c874c842..2e60e9e9 100644 --- a/entwine/reader/query.hpp +++ b/entwine/reader/query.hpp @@ -60,6 +60,7 @@ class Query void processPoint(const PointInfo& info); const Reader& m_reader; + const QueryParams m_params; const Metadata& m_metadata; const Structure& m_structure; const Delta m_delta; @@ -167,11 +168,27 @@ class ReadQuery : public Query private: void setScaled(const DimInfo& dim, std::size_t dimNum, char* pos) { - const double d = Point::scale( - m_pointRef.getFieldAs(dim.id()), - m_mid[dimNum], - m_delta.scale()[dimNum], - m_delta.offset()[dimNum]); + double d(0); + if (m_params.nativeBounds()) + { + d = Point::unscale( + m_pointRef.getFieldAs(dim.id()), + m_metadata.delta()->scale()[dimNum], + m_metadata.delta()->offset()[dimNum]); + + d = Point::scale( + d, + m_delta.scale()[dimNum], + m_delta.offset()[dimNum]); + } + else + { + d = Point::scale( + m_pointRef.getFieldAs(dim.id()), + m_mid[dimNum], + m_delta.scale()[dimNum], + m_delta.offset()[dimNum]); + } switch (dim.type()) {