diff --git a/io/TIndexReader.cpp b/io/TIndexReader.cpp index 80cb65c175..c0de7bf4eb 100644 --- a/io/TIndexReader.cpp +++ b/io/TIndexReader.cpp @@ -36,6 +36,7 @@ #include #include #include +#include namespace pdal { diff --git a/kernels/TIndexKernel.cpp b/kernels/TIndexKernel.cpp index 51e31bd12f..e4aff7a54b 100644 --- a/kernels/TIndexKernel.cpp +++ b/kernels/TIndexKernel.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include "../io/LasWriter.hpp" @@ -429,8 +430,7 @@ bool TIndexKernel::createFeature(const FieldIndexes& indexes, if (fileInfo.m_srs.empty() || m_overrideASrs) fileInfo.m_srs = m_assignSrsString; - SpatialRef srcSrs(fileInfo.m_srs); - if (srcSrs.empty()) + if (fileInfo.m_srs.empty()) { std::ostringstream oss; @@ -567,9 +567,7 @@ bool TIndexKernel::openLayer(const std::string& layerName) bool TIndexKernel::createLayer(std::string const& layername) { - using namespace gdal; - - SpatialRef srs(m_tgtSrsString); + gdal::SpatialRef srs(m_tgtSrsString); if (!srs) m_log->get(LogLevel::Error) << "Unable to import srs for layer " "creation" << std::endl; diff --git a/kernels/private/density/OGR.cpp b/kernels/private/density/OGR.cpp index 05861f7e2f..5ce2b82e26 100644 --- a/kernels/private/density/OGR.cpp +++ b/kernels/private/density/OGR.cpp @@ -39,6 +39,7 @@ #include #include +#include #include "../filters/private/hexer/HexGrid.hpp" #include "../filters/private/hexer/HexIter.hpp" @@ -112,16 +113,15 @@ OGRGeometryH collectHexagon(hexer::HexInfo const& info, } // unnamed namespace -OGR::OGR(std::string const& filename, std::string srs, std::string driver, - std::string layerName) +OGR::OGR(std::string const& filename, const std::string& wkt, + std::string driver, std::string layerName) : m_filename(filename) , m_driver(driver) - , m_srs(srs) , m_ds(0) , m_layer(0) , m_layerName(layerName) { - createLayer(); + createLayer(wkt); } @@ -131,7 +131,7 @@ OGR::~OGR() } -void OGR::createLayer() +void OGR::createLayer(const std::string& wkt) { OGRSFDriverH driver = OGRGetDriverByName(m_driver.c_str()); if (driver == NULL) @@ -151,7 +151,8 @@ void OGR::createLayer() if (m_layerName.empty()) m_layerName = m_filename; - m_layer = GDALDatasetCreateLayer(m_ds, m_layerName.c_str(), m_srs.get(), + gdal::SpatialRef srs(wkt); + m_layer = GDALDatasetCreateLayer(m_ds, m_layerName.c_str(), srs.get(), wkbMultiPolygon, NULL); if (m_layer == NULL) throw pdal_error("Layer creation was null!"); diff --git a/kernels/private/density/OGR.hpp b/kernels/private/density/OGR.hpp index 39ce1b2501..ed3f52dd36 100644 --- a/kernels/private/density/OGR.hpp +++ b/kernels/private/density/OGR.hpp @@ -52,7 +52,7 @@ class OGR { public: - OGR(std::string const& filename, std::string srs, + OGR(std::string const& filename, const std::string& srs, std::string driver = "ESRI Shapefile", std::string layerName =""); ~OGR(); @@ -62,13 +62,12 @@ class OGR private: std::string m_filename; std::string m_driver; - gdal::SpatialRef m_srs; OGRDataSourceH m_ds; OGRLayerH m_layer; std::string m_layerName; - void createLayer(); + void createLayer(const std::string& wkt); }; } // namespace pdal diff --git a/pdal/GDALUtils.cpp b/pdal/GDALUtils.cpp index 5bb5373f51..dbb8e001bf 100644 --- a/pdal/GDALUtils.cpp +++ b/pdal/GDALUtils.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -1008,6 +1009,7 @@ std::vector getPolygons(const NL::json& ogr) poLayer = ds->ExecuteSQL(query.c_str(), NULL, dialect.c_str()); if (!poLayer) throw pdal_error("Unable to execute OGR SQL query."); + SpatialRef sref; sref.setFromLayer(poLayer); ds->ReleaseResultSet(poLayer); @@ -1021,6 +1023,7 @@ std::vector getPolygons(const NL::json& ogr) } else poly.setSpatialReference(sref.wkt()); + geom = (OGRGeometry *)poly.getOGRHandle(); } } diff --git a/pdal/GDALUtils.hpp b/pdal/GDALUtils.hpp index e6c345f459..4995ca0dbb 100644 --- a/pdal/GDALUtils.hpp +++ b/pdal/GDALUtils.hpp @@ -77,65 +77,6 @@ PDAL_DLL bool reproject(double& x, double& y, double& z, const SpatialReference& srcSrs, const SpatialReference& dstSrs); PDAL_DLL std::string lastError(); -typedef std::shared_ptr RefPtr; - -class SpatialRef -{ -public: - SpatialRef() - { newRef(OSRNewSpatialReference("")); } - SpatialRef(const std::string& srs) - { - newRef(OSRNewSpatialReference("")); - if (OSRSetFromUserInput(get(), srs.data()) != OGRERR_NONE) - m_ref.reset(); - } - - void setFromLayer(OGRLayerH layer) - { - if (layer) - { - OGRSpatialReferenceH s = OGR_L_GetSpatialRef(layer); - if (s) - { - OGRSpatialReferenceH clone = OSRClone(s); - newRef(clone); - } - } - } - operator bool () const - { return m_ref.get() != NULL; } - OGRSpatialReferenceH get() const - { return m_ref.get(); } - std::string wkt() const - { - std::string output; - - if (m_ref.get()) - { - char *pszWKT = NULL; - OSRExportToWkt(m_ref.get(), &pszWKT); - bool valid = (bool)*pszWKT; - output = pszWKT; - CPLFree(pszWKT); - } - return output; - } - - bool empty() const - { - return wkt().empty(); - } - -private: - void newRef(void *v) - { - m_ref = RefPtr(v, [](void* t){ OSRDestroySpatialReference(t); } ); - } - - RefPtr m_ref; -}; - // This is a little confusing because we have a singleton error handler with // a single log pointer, but we set the log pointer/debug state as if we diff --git a/pdal/private/gdal/SpatialRef.cpp b/pdal/private/gdal/SpatialRef.cpp new file mode 100644 index 0000000000..049867e696 --- /dev/null +++ b/pdal/private/gdal/SpatialRef.cpp @@ -0,0 +1,115 @@ +/****************************************************************************** +* Copyright (c) 2020, Hobu Inc. +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following +* conditions are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided +* with the distribution. +* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the +* names of its contributors may be used to endorse or promote +* products derived from this software without specific prior +* written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +****************************************************************************/ + +#include + +#include +#include +#include + +#include "SpatialRef.hpp" + +namespace pdal +{ +namespace gdal +{ + +SpatialRef::SpatialRef() +{ + newRef(OSRNewSpatialReference("")); +} + + +SpatialRef::SpatialRef(const std::string& srs) +{ + newRef(OSRNewSpatialReference("")); + if (OSRSetFromUserInput(get(), srs.data()) != OGRERR_NONE) + m_ref.reset(); +} + + +void SpatialRef::setFromLayer(OGRLayerH layer) +{ + if (layer) + { + OGRSpatialReferenceH s = OGR_L_GetSpatialRef(layer); + if (s) + { + OGRSpatialReferenceH clone = OSRClone(s); + newRef(clone); + } + } +} + + +SpatialRef::operator bool () const +{ + return m_ref.get() != NULL; +} + + +OGRSpatialReferenceH SpatialRef::get() const +{ + return m_ref.get(); +} + + +std::string SpatialRef::wkt() const +{ + std::string output; + + if (m_ref.get()) + { + char *pszWKT = NULL; + OSRExportToWkt(m_ref.get(), &pszWKT); + bool valid = (bool)*pszWKT; + output = pszWKT; + CPLFree(pszWKT); + } + return output; +} + + +bool SpatialRef::empty() const +{ + return wkt().empty(); +} + +void SpatialRef::newRef(void *v) +{ + m_ref = RefPtr(v, [](void* t){ OSRDestroySpatialReference(t); } ); +} + +} // namespace gdal +} // namespace pdal diff --git a/pdal/private/gdal/SpatialRef.hpp b/pdal/private/gdal/SpatialRef.hpp new file mode 100644 index 0000000000..368a1c6262 --- /dev/null +++ b/pdal/private/gdal/SpatialRef.hpp @@ -0,0 +1,65 @@ +/****************************************************************************** +* Copyright (c) 2020, Hobu Inc. +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following +* conditions are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided +* with the distribution. +* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the +* names of its contributors may be used to endorse or promote +* products derived from this software without specific prior +* written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +****************************************************************************/ + +#pragma once + +#include + +namespace pdal +{ +namespace gdal +{ + +class SpatialRef +{ + using OGRLayerH = void *; + typedef std::shared_ptr RefPtr; +public: + SpatialRef(); + SpatialRef(const std::string& srs); + + void setFromLayer(OGRLayerH layer); + operator bool () const; + OGRSpatialReferenceH get() const; + std::string wkt() const; + bool empty() const; + +private: + void newRef(void *v); + + RefPtr m_ref; +}; + +} // namespace gdal +} // namespace pdal