From 26de271c8ffcdb3b4d5dc3bf84550adc1cea45d7 Mon Sep 17 00:00:00 2001 From: Andrew Bell Date: Thu, 5 Feb 2015 10:35:34 -0600 Subject: [PATCH] Add output_dims support. --- doc/stages/writers.oci.rst | 13 +++++++++-- doc/stages/writers.pgpointcloud.rst | 14 +++++++++--- include/pdal/DbWriter.hpp | 2 ++ include/pdal/PointContext.hpp | 8 ++++++- include/pdal/Stage.hpp | 2 ++ include/pdal/Writer.hpp | 1 + plugins/pgpointcloud/io/PgWriter.cpp | 24 ++++++++------------- plugins/pgpointcloud/io/PgWriter.hpp | 4 +--- src/DbWriter.cpp | 32 +++++++++++++++++++++++++++- src/Stage.cpp | 1 + src/Writer.cpp | 2 ++ 11 files changed, 78 insertions(+), 25 deletions(-) diff --git a/doc/stages/writers.oci.rst b/doc/stages/writers.oci.rst index a75f2d73f9..415d994e72 100644 --- a/doc/stages/writers.oci.rst +++ b/doc/stages/writers.oci.rst @@ -151,8 +151,17 @@ stream_chunks blob_chunk_count When streaming, the number of chunks per write to use [Default: **16**] - - +scale_x, scale_y, scale_z / offset_x, offset_y, offset_z + If ANY of these options are specified the X, Y and Z dimensions are adjusted + by subtracting the offset and then dividing the values by the specified + scaling factor before being written as 32-bit integers (as opposed to double + precision values). If any of these options is specified, unspecified + scale_ options are given the value of 1.0 and unspecified + offset_ are given the value of 0.0. + +output_dims + If specified, limits the dimensions written for each point. Dimensions + are listed by name and separated by commas. .. _Oracle point cloud: http://docs.oracle.com/cd/B28359_01/appdev.111/b28400/sdo_pc_pkg_ref.htm diff --git a/doc/stages/writers.pgpointcloud.rst b/doc/stages/writers.pgpointcloud.rst index 8bf892e23e..dd6689925a 100644 --- a/doc/stages/writers.pgpointcloud.rst +++ b/doc/stages/writers.pgpointcloud.rst @@ -61,9 +61,6 @@ compression overwrite To drop the table before writing set to 'true'. To append to the table set to 'false'. [Default: **true**] -pack_ignored_fields - Remove ignored fields from schema before creating schema object in pointcloud_schemas. [Default: **true**] - srid Spatial reference ID (relative to the `spatial_ref_sys` table in PostGIS) to store with the point cloud schema. [Default: **4326**] @@ -73,5 +70,16 @@ pre_sql post_sql Optional SQL to execute *after* running the translation. If the value references a file, the file is read and any SQL inside is executed. Otherwise the value is executed as SQL itself. +scale_x, scale_y, scale_z / offset_x, offset_y, offset_z + If ANY of these options are specified the X, Y and Z dimensions are adjusted + by subtracting the offset and then dividing the values by the specified + scaling factor before being written as 32-bit integers (as opposed to double + precision values). If any of these options is specified, unspecified + scale_ options are given the value of 1.0 and unspecified + offset_ are given the value of 0.0. + +output_dims + If specified, limits the dimensions written for each point. Dimensions + are listed by name and separated by commas. .. _PostgreSQL Pointcloud: http://github.com/pramsey/pointcloud diff --git a/include/pdal/DbWriter.hpp b/include/pdal/DbWriter.hpp index da1d43d840..25f3f78801 100644 --- a/include/pdal/DbWriter.hpp +++ b/include/pdal/DbWriter.hpp @@ -59,7 +59,9 @@ class PDAL_DLL DbWriter : public Writer size_t readPoint(const PointBuffer& pb, PointId idx, char *outbuf); private: + virtual void prepared(PointContextRef ctx); virtual void ready(PointContextRef ctx); + DimTypeList dimTypes(PointContextRef ctx); DimTypeList m_dimTypes; int m_xPackedOffset; diff --git a/include/pdal/PointContext.hpp b/include/pdal/PointContext.hpp index 548dd99e05..6d85210470 100644 --- a/include/pdal/PointContext.hpp +++ b/include/pdal/PointContext.hpp @@ -169,10 +169,16 @@ class PointContext const Dimension::IdList& ids = dims(); for (auto ii = ids.begin(); ii != ids.end(); ++ii) - dimTypes.push_back(DimType (*ii, dimType(*ii))); + dimTypes.push_back(DimType(*ii, dimType(*ii))); return dimTypes; } + DimType findDimType(const std::string& name) const + { + Dimension::Id::Enum id = findDim(name); + return DimType(id, dimType(id)); + } + Dimension::Id::Enum findDim(const std::string& name) const { Dimension::Id::Enum id = Dimension::id(name); diff --git a/include/pdal/Stage.hpp b/include/pdal/Stage.hpp index fba8c9335c..9a7b537f73 100644 --- a/include/pdal/Stage.hpp +++ b/include/pdal/Stage.hpp @@ -164,6 +164,8 @@ class PDAL_DLL Stage {} virtual void addDimensions(PointContextRef ctx) { (void)ctx; } + virtual void prepared(PointContextRef ctx) + { (void)ctx; } virtual void ready(PointContextRef ctx) { (void)ctx; } virtual void done(PointContextRef ctx) diff --git a/include/pdal/Writer.hpp b/include/pdal/Writer.hpp index 882ff22ac8..b1d5aa45a4 100644 --- a/include/pdal/Writer.hpp +++ b/include/pdal/Writer.hpp @@ -75,6 +75,7 @@ class PDAL_DLL Writer : public Stage XForm m_xXform; XForm m_yXform; XForm m_zXform; + std::vector m_outputDims; void setAutoOffset(const PointBuffer& buf); diff --git a/plugins/pgpointcloud/io/PgWriter.cpp b/plugins/pgpointcloud/io/PgWriter.cpp index 5cc1955701..38cbfb9223 100644 --- a/plugins/pgpointcloud/io/PgWriter.cpp +++ b/plugins/pgpointcloud/io/PgWriter.cpp @@ -67,8 +67,6 @@ PgWriter::PgWriter() , m_patch_capacity(400) , m_srid(0) , m_pcid(0) - , m_have_postgis(false) - , m_create_index(true) , m_overwrite(true) , m_schema_is_initialized(false) {} @@ -88,7 +86,7 @@ void PgWriter::processOptions(const Options& options) // Schema and column name can be defaulted safely m_column_name = options.getValueOrDefault("column", "pa"); - m_schema_name = options.getValueOrDefault("schema", ""); + m_schema_name = options.getValueOrDefault("schema"); // // Read compression type and turn into an integer std::string compression_str = @@ -103,8 +101,10 @@ void PgWriter::processOptions(const Options& options) m_patch_capacity = options.getValueOrDefault("capacity", 400); m_srid = options.getValueOrDefault("srid", 4326); m_pcid = options.getValueOrDefault("pcid", 0); - m_pack = options.getValueOrDefault("pack_ignored_fields", true); - m_pre_sql = getOptions().getValueOrDefault("pre_sql", ""); + m_pre_sql = options.getValueOrDefault("pre_sql"); + // Post-SQL can be *either* a SQL file to execute, *or* a SQL statement + // to execute. We find out which one here. + std::string post_sql = options.getValueOrDefault("post_sql"); } // @@ -204,23 +204,17 @@ void PgWriter::write(const PointBuffer& buffer) void PgWriter::done(PointContextRef ctx) { - if (m_create_index && m_have_postgis) - { - CreateIndex(m_schema_name, m_table_name, m_column_name); - } + //CreateIndex(m_schema_name, m_table_name, m_column_name); - // Post-SQL can be *either* a SQL file to execute, *or* a SQL statement - // to execute. We find out which one here. - std::string post_sql = getOptions().getValueOrDefault("post_sql", ""); - if (post_sql.size()) + if (m_post_sql.size()) { - std::string sql = FileUtils::readFileAsString(post_sql); + std::string sql = FileUtils::readFileAsString(m_post_sql); if (!sql.size()) { // if there was no file to read because the data in post_sql was // actually the sql code the user wanted to run instead of the // filename to open, we'll use that instead. - sql = post_sql; + sql = m_post_sql; } pg_execute(m_session, sql); } diff --git a/plugins/pgpointcloud/io/PgWriter.hpp b/plugins/pgpointcloud/io/PgWriter.hpp index 5b8b1b68f8..af512fd5cc 100644 --- a/plugins/pgpointcloud/io/PgWriter.hpp +++ b/plugins/pgpointcloud/io/PgWriter.hpp @@ -95,13 +95,11 @@ class PDAL_DLL PgWriter : public DbWriter uint32_t m_patch_capacity; uint32_t m_srid; uint32_t m_pcid; - bool m_have_postgis; - bool m_create_index; bool m_overwrite; std::string m_insert; Orientation::Enum m_orientation; - bool m_pack; std::string m_pre_sql; + std::string m_post_sql; // lose this bool m_schema_is_initialized; diff --git a/src/DbWriter.cpp b/src/DbWriter.cpp index d2401a5457..5ed9ea240d 100644 --- a/src/DbWriter.cpp +++ b/src/DbWriter.cpp @@ -35,6 +35,37 @@ namespace pdal { +DimTypeList DbWriter::dimTypes(PointContextRef ctx) +{ + using namespace Dimension; + + if (m_outputDims.empty()) + return ctx.dimTypes(); + + DimTypeList dims; + for (std::string& s : m_outputDims) + { + DimType dt = ctx.findDimType(s); + if (dt.m_id == Id::Unknown) + { + std::ostringstream oss; + oss << "Invalid dimension '" << s << "' specified for " + "'output_dims' option."; + throw pdal_error(oss.str()); + } + dims.push_back(dt); + } + return dims; +} + + +// Placing this here allows validation of dimensions before execution begins. +void DbWriter::prepared(PointContextRef ctx) +{ + m_dimTypes = dimTypes(ctx); +} + + void DbWriter::ready(PointContextRef ctx) { using namespace Dimension; @@ -43,7 +74,6 @@ void DbWriter::ready(PointContextRef ctx) // a scale factor and offset instead of being written as Double. m_locationScaling = (m_xXform.nonstandard() || m_yXform.nonstandard() || m_zXform.nonstandard()); - m_dimTypes = ctx.dimTypes(); auto cmp = [](const DimType& d1, const DimType& d2) -> bool { diff --git a/src/Stage.cpp b/src/Stage.cpp index 5c580f8c16..a6125ad8b1 100644 --- a/src/Stage.cpp +++ b/src/Stage.cpp @@ -68,6 +68,7 @@ void Stage::prepare(PointContextRef ctx) l_initialize(ctx); initialize(); addDimensions(ctx); + prepared(ctx); } diff --git a/src/Writer.cpp b/src/Writer.cpp index 87ee32fcff..901c8b45b3 100644 --- a/src/Writer.cpp +++ b/src/Writer.cpp @@ -71,6 +71,8 @@ void Writer::writerProcessOptions(const Options& options) m_yXform.m_scale = options.getValueOrThrow("scale_y"); if (options.hasOption("scale_z")) m_zXform.m_scale = options.getValueOrThrow("scale_z"); + m_outputDims = + options.getValueOrDefault>("output_dims"); }