diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx index b6056f02eff064efccf3c5cf50a67b432447be31..cbe8ebd372edd91d03c6ca4cb6ea139113a5867a 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx @@ -28,39 +28,15 @@ #include <boost/range/end.hpp> // ITK includes #include "itkMacro.h" // itkExceptionMacro -#include "itkMetaDataObject.h" #include "itkExceptionObject.h" #include "itksys/SystemTools.hxx" // OTB includes #include "otbMacro.h" -#include "otbMetaDataKey.h" #include "otbOGRDriversInit.h" #include "otbSystem.h" // OGR includes #include "ogrsf_frmts.h" -void -otb::ogr::DataSource -::SetProjectionRef(const std::string& projectionRef) -{ - itk::MetaDataDictionary& dict = this->GetMetaDataDictionary(); - itk::EncapsulateMetaData<std::string>( - dict, MetaDataKey::ProjectionRefKey, projectionRef); - this->Modified(); -} - -std::string -otb::ogr::DataSource -::GetProjectionRef() const -{ - const itk::MetaDataDictionary& dict = this->GetMetaDataDictionary(); - - std::string projectionRef; - itk::ExposeMetaData<std::string>(dict, MetaDataKey::ProjectionRefKey, projectionRef); - - return projectionRef; -} - /*===========================================================================*/ /*=======================[ construction/destruction ]========================*/ /*===========================================================================*/ @@ -256,7 +232,7 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer( << "> in the OGRDataSource file <" << m_DataSource->GetName() <<">: " << CPLGetLastErrorMsg()); } - Layer l(ol, this); + Layer l(ol/*, this*/); return l; } @@ -275,7 +251,7 @@ otb::ogr::Layer otb::ogr::DataSource::CopyLayer( << "> in the OGRDataSource file <" << m_DataSource->GetName() <<">: " << CPLGetLastErrorMsg()); } - Layer l(ol, this); + Layer l(ol/*, this*/); return l; } @@ -310,7 +286,7 @@ otb::ogr::Layer otb::ogr::DataSource::GetLayerChecked(size_t i) itkExceptionMacro( << "Unexpected error: cannot fetch " << i << "th layer in the OGRDataSource <" << m_DataSource->GetName() << ">: " << CPLGetLastErrorMsg()); } - return otb::ogr::Layer(layer_ptr, this); + return otb::ogr::Layer(layer_ptr/*, this*/); } OGRLayer* otb::ogr::DataSource::GetLayerUnchecked(size_t i) @@ -324,7 +300,7 @@ otb::ogr::Layer otb::ogr::DataSource::GetLayer(std::string const& name) { assert(m_DataSource && "Datasource not initialized"); OGRLayer * layer_ptr = m_DataSource->GetLayerByName(name.c_str()); - return otb::ogr::Layer(layer_ptr, this); + return otb::ogr::Layer(layer_ptr/*, this*/); } @@ -338,7 +314,7 @@ otb::ogr::Layer otb::ogr::DataSource::GetLayerChecked(std::string const& name) << "> in the OGRDataSource <" << m_DataSource->GetName() << ">: " << CPLGetLastErrorMsg()); } - return otb::ogr::Layer(layer_ptr, this); + return otb::ogr::Layer(layer_ptr/*, this*/); } int otb::ogr::DataSource::GetLayersCount() const @@ -364,7 +340,7 @@ otb::ogr::Layer otb::ogr::DataSource::ExecuteSQL( // Cannot use the deleter made for result sets obtained from // OGRDataSource::ExecuteSQL because it checks for non-nullity.... // *sigh* - return otb::ogr::Layer(0, 0); + return otb::ogr::Layer(0/*, 0*/); #endif } return otb::ogr::Layer(layer_ptr, *m_DataSource); @@ -402,81 +378,77 @@ int otb::ogr::DataSource::Size(bool doForceComputation) const /*=================================[ Misc ]==================================*/ /*===========================================================================*/ -std::string otb::ogr::DataSource::GetGlobalExtent(double & ulx, - double & uly, - double & lrx, - double & lry, - bool force) const +OGREnvelope otb::ogr::DataSource::GetGlobalExtent(bool force/* = false */, std::string *outwkt) const { - OGREnvelope sExtent; - + assert(m_DataSource && "Datasource not initialized"); const_iterator lit = this->begin(); - + if(lit==this->end()) { itkGenericExceptionMacro(<< "Cannot compute global extent because there are no layers in the DataSource"); } - std::string outwkt = lit->GetProjectionRef(); - const OGRSpatialReference * ref_srs = lit->GetSpatialRef(); - - const OGRErr res = lit->ogr().GetExtent(&sExtent,force); - + OGREnvelope sExtent = lit->GetExtent(force); - if(res!= OGRERR_NONE) - { - itkGenericExceptionMacro(<< "Cannot retrieve extent of layer <" - <<lit->GetName()<<">: " << CPLGetLastErrorMsg()); - } - ++lit; for(; lit!=this->end(); ++lit) { - OGREnvelope cExtent; - - const OGRErr cres = lit->ogr().GetExtent(&cExtent,force); - - if(cres!= OGRERR_NONE) - { - itkGenericExceptionMacro(<< "Cannot retrieve extent of layer <" - <<lit->GetName()<<">: " << CPLGetLastErrorMsg()); - } - - const OGRSpatialReference * current_srs = lit->GetSpatialRef(); - - // If both srs are valid and if they are different - if(ref_srs && current_srs && current_srs->IsSame(ref_srs) == 0) - { - // Reproject cExtent in ref_srs - // OGRCreateCoordinateTransformation is not const-correct - OGRCoordinateTransformation * coordTransformation = OGRCreateCoordinateTransformation( - const_cast<OGRSpatialReference *>(current_srs), - const_cast<OGRSpatialReference *>(ref_srs)); - - coordTransformation->Transform(1,&cExtent.MinX,&cExtent.MinY); - coordTransformation->Transform(1,&cExtent.MaxX,&cExtent.MaxY); - - double real_minx = std::min(cExtent.MinX,cExtent.MaxX); - double real_miny = std::min(cExtent.MinY,cExtent.MaxY); - double real_maxx = std::max(cExtent.MinX,cExtent.MaxX); - double real_maxy = std::max(cExtent.MinY,cExtent.MaxY); - - cExtent.MinX = real_minx; - cExtent.MinY = real_miny; - cExtent.MaxX = real_maxx; - cExtent.MaxY = real_maxy; - - CPLFree(coordTransformation); - } - - // If srs are invalid, we assume that extent are coherent - - // Merge with previous layer - sExtent.Merge(cExtent); + OGREnvelope cExtent = lit->GetExtent(force); // may throw + + const OGRSpatialReference * current_srs = lit->GetSpatialRef(); + + // If both srs are valid and if they are different + if(ref_srs && current_srs && current_srs->IsSame(ref_srs) == 0) + { + // Reproject cExtent in ref_srs + // OGRCreateCoordinateTransformation is not const-correct + OGRCoordinateTransformation * coordTransformation = OGRCreateCoordinateTransformation( + const_cast<OGRSpatialReference *>(current_srs), + const_cast<OGRSpatialReference *>(ref_srs)); + + coordTransformation->Transform(1,&cExtent.MinX,&cExtent.MinY); + coordTransformation->Transform(1,&cExtent.MaxX,&cExtent.MaxY); + + const double real_minx = std::min(cExtent.MinX,cExtent.MaxX); + const double real_miny = std::min(cExtent.MinY,cExtent.MaxY); + const double real_maxx = std::max(cExtent.MinX,cExtent.MaxX); + const double real_maxy = std::max(cExtent.MinY,cExtent.MaxY); + + cExtent.MinX = real_minx; + cExtent.MinY = real_miny; + cExtent.MaxX = real_maxx; + cExtent.MaxY = real_maxy; + +#if GDAL_VERSION_NUM >= 1700 + OGRCoordinateTransformation::DestroyCT(coordTransformation); +#else +#warning the following resource release may crash, please update your version of GDAL + delete coordTransformation; // note there is no garanty +#endif + } + // else: If srs are invalid, we assume that extent are coherent + + // Merge with previous layers' extent + sExtent.Merge(cExtent); + } // for each layer + + if (outwkt) + { + *outwkt = lit->GetProjectionRef(); } + return sExtent; +} +std::string otb::ogr::DataSource::GetGlobalExtent(double & ulx, + double & uly, + double & lrx, + double & lry, + bool force) const +{ + std::string outwkt; + const OGREnvelope sExtent = GetGlobalExtent(force, &outwkt); ulx = sExtent.MinX; uly = sExtent.MinY; lrx = sExtent.MaxX; diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h index 4f5babf28e549ae5056ae25f227e0c3ff656fc3f..a390c3c93343a1bc3246dd7adcbabb77221aadf8 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h @@ -123,8 +123,10 @@ public: /**\name Projection Reference property */ //@{ +#if 0 void SetProjectionRef(const std::string& projectionRef); std::string GetProjectionRef() const; +#endif //@} /** Clears the data source. @@ -212,26 +214,28 @@ public: */ int Size(bool doForceComputation) const; - /** Allow to retrieve the union of the extents of all - * layers. In case of multiple layers with different SRS, the - * global extent is expressed in the SRS of the first layer. - * \param[out] ulx reference to upper-left x coordinate of the - * extent - * \param[out] uly reference to upper-left y coordinate of the - * extent - * \param[out] lrx reference to lower-right x coordinate of the - * extent - * \param[out] uly reference to lower-right y coordinate of the - * extent - * \param[in] force Force computation of layers extents if not - * available. May force the driver to walk all geometries to - * compute the extent. - * \return The Wkt of the extent projection (which is the wkt of - * the first layer SRS) + /** Retrieves the union of the extents of all layers. + * \param[out] ulx reference to upper-left x coordinate of the extent + * \param[out] uly reference to upper-left y coordinate of the extent + * \param[out] lrx reference to lower-right x coordinate of the extent + * \param[out] uly reference to lower-right y coordinate of the extent + * \param[in] force Force computation of layers extents if not available. May + * force the driver to walk all geometries to compute the extent. + * \return The Wkt of the extent projection (which is the wkt of the first + * layer SRS) * \throw itk::ExceptionObject if the layers extents can not be retrieved. */ - std::string GetGlobalExtent(double & ulx, double & uly, double & lrx, double & lry, bool force = false) const; - + std::string GetGlobalExtent(double & ulx, double & uly, double & lrx, double & lry, bool force = false) const; + + /** Retrieves the union of the extents of all layers. + * \param[in] force Force computation of layers extents if not available. May + * force the driver to walk all geometries to compute the extent. + * \param[out] outwkt The Wkt of the extent projection (which is the wkt of + * the first layer SRS); if null, nothing is returned this way + * \return the extent of all layers + * \throw itk::ExceptionObject if the layers extents can not be retrieved. + */ + OGREnvelope GetGlobalExtent(bool force = false, std::string * outwkt=0) const; /** Grafts data and information from one data source to another. * \deprecated \c OGRLayer has an embedded input iterator. As a consequence, diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx index f56d3d5283bb3af4f29ab73f0dc5b10c17697610..fc69791aa99176627e25b6f16b652689db0060a2 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx @@ -50,7 +50,7 @@ otb::ogr::Layer otb::ogr::DataSource::GetLayer(size_t i) assert(int(i) < GetLayersCount() && "Out-of-range index"); OGRLayer * layer_ptr = GetLayerUnchecked(i); assert(layer_ptr && "No layer returned by OGR"); - return otb::ogr::Layer(layer_ptr, this); + return otb::ogr::Layer(layer_ptr/*, this*/); } inline @@ -123,7 +123,7 @@ Value otb::ogr::DataSource::layer_iter<Value>::dereference() const assert(m_DataSource && int(m_index) < m_DataSource->GetLayersCount() && "cannot dereference past end()"); - return Value(m_DataSource->GetLayerUnchecked(m_index), const_cast <DataSource*>(m_DataSource)); + return Value(m_DataSource->GetLayerUnchecked(m_index)/*, const_cast <DataSource*>(m_DataSource)*/); } diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx index 872823276c87bf9e8c49de03468d75deedd98e05..a2ef0d837f1a47c852476da678b67f2380574d10 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx @@ -44,9 +44,11 @@ namespace { // Anonymous namespace } // Anonymous namespace -otb::ogr::Layer::Layer(OGRLayer* layer, DataSourcePtr datasource) +otb::ogr::Layer::Layer(OGRLayer* layer/*, DataSourcePtr datasource*/) : m_Layer(layer, LeaveAloneDeleter()) -, m_DataSource(datasource) +#if 0 + , m_DataSource(datasource) +#endif { } @@ -158,16 +160,22 @@ std::string otb::ogr::Layer::GetName() const #endif } -void otb::ogr::Layer::GetExtent(double& ulx, double& uly, double& lrx, double& lry, bool force) const +OGREnvelope otb::ogr::Layer::GetExtent(bool force/* = false */) const { + assert(m_Layer && "OGRLayer not initialized"); OGREnvelope sExtent; const OGRErr res = m_Layer->GetExtent(&sExtent,force); if(res != OGRERR_NONE) { - itkGenericExceptionMacro(<< "Cannot retrieve extent of layer <" - <<GetName()<<">: " << CPLGetLastErrorMsg()); + itkGenericExceptionMacro(<< "Cannot retrieve extent of layer <" + <<GetName()<<">: " << CPLGetLastErrorMsg()); } + return sExtent; +} +void otb::ogr::Layer::GetExtent(double& ulx, double& uly, double& lrx, double& lry, bool force) const +{ + const OGREnvelope sExtent = GetExtent(force); ulx = sExtent.MinX; uly = sExtent.MinY; lrx = sExtent.MaxX; @@ -231,13 +239,9 @@ OGRSpatialReference const* otb::ogr::Layer::GetSpatialRef() const std::string otb::ogr::Layer::GetProjectionRef() const { - char * wkt; - std::string stringWkt = ""; - assert(m_Layer && "OGRLayer not initialized"); - - OGRSpatialReference * srs = m_Layer->GetSpatialRef(); - + char * wkt = 0; + OGRSpatialReference const* srs = GetSpatialRef(); if(srs) { const OGRErr res = srs->exportToWkt(&wkt); @@ -245,16 +249,17 @@ std::string otb::ogr::Layer::GetProjectionRef() const if(res != OGRERR_NONE) { itkGenericExceptionMacro(<< "Cannot convert spatial reference to wkt string for layer <" - <<m_Layer->GetName()<<">: " << CPLGetLastErrorMsg()); + <<m_Layer->GetName()<<">: " << CPLGetLastErrorMsg()); } - stringWkt = wkt; - // According to documentation, argument of exportToWkt() should be - // freed + assert(wkt); + const std::string stringWkt(wkt); + // According to documentation, argument of exportToWkt() should be freed CPLFree(wkt); + return stringWkt; } - return stringWkt; + return ""; } /*===========================================================================*/ @@ -377,12 +382,3 @@ bool otb::ogr::operator==(Layer const& lhs, Layer const& rhs) const bool equal = lhs.m_Layer.get() == rhs.m_Layer.get(); return equal; } - -itk::MetaDataDictionary & otb::ogr::Layer::GetMetaDataDictionary() -{ - if (!m_DataSource) - { - itkGenericExceptionMacro(<<"Cannot acces metadata dictionary from a layer constructed with an SQL request."); - } - return m_DataSource->GetMetaDataDictionary(); -} diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h index f8ff643237d7b0b452537362709ca958bd25b531..1071ab001289d41e76bbd500703377e3a335df42 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h @@ -32,12 +32,6 @@ class OGRDataSource; class OGRGeometry; class OGRFeatureDefn; -namespace itk -{ -class MetaDataDictionary; -} // itk namespace - - namespace otb { namespace ogr { class DataSource; class Layer; @@ -76,7 +70,9 @@ public: itkTypeMacro(Layer, void); //@} +#if 0 typedef itk::SmartPointer<DataSource> DataSourcePtr; +#endif /**\name Construction */ //@{ @@ -91,7 +87,7 @@ public: * is deleted, the layer won't be usable anymore. Unfortunatelly, there is no * mean to report this to this layer proxy. */ - Layer(OGRLayer* layer, DataSourcePtr datasource); + Layer(OGRLayer* layer/*, DataSourcePtr datasource*/); /** * Init constructor for layers that need to be released. @@ -189,18 +185,21 @@ public: */ std::string GetName() const; - /** Allow to retrieve the extent of the layer - * \param[out] ulx reference to upper-left x coordinate of the - * extent - * \param[out] uly reference to upper-left y coordinate of the - * extent - * \param[out] lrx reference to lower-right x coordinate of the - * extent - * \param[out] uly reference to lower-right y coordinate of the - * extent - * \param[in] force Force computation of the extent if not - * available. May force the driver to walk all geometries to - * compute the extent. + /** Retrieves the extent of the layer. + * \param[in] force Force computation of the extent if not available. May + * force the driver to walk all geometries to compute the extent. + * \return the extent of the layer + * \throw itk::ExceptionObject if the extent can not be retrieved. + */ + OGREnvelope GetExtent(bool force = false) const; + + /** Retrieves the extent of the layer. + * \param[out] ulx reference to upper-left x coordinate of the extent + * \param[out] uly reference to upper-left y coordinate of the extent + * \param[out] lrx reference to lower-right x coordinate of the extent + * \param[out] uly reference to lower-right y coordinate of the extent + * \param[in] force Force computation of the extent if not available. May + * force the driver to walk all geometries to compute the extent. * \throw itk::ExceptionObject if the extent can not be retrieved. */ void GetExtent(double & ulx, double & uly, double & lrx, double & lry, bool force = false) const; @@ -277,13 +276,14 @@ public: void SetSpatialFilterRect(double dfMinX, double dfMinY, double dfMaxX, double dfMaxY); //@} - /**Spatial Reference property. + /** Spatial Reference property. + * \note Read-only property. In order to set this property, you'll have to + * create a new layer with a spatial reference. * \internal the I/O spatial reference is an undeletable pointer, that may be null. - * \note Read-only property */ OGRSpatialReference const* GetSpatialRef() const; - /** Returns the projection ref associated with the layer + /** Returns the projection ref associated with the layer. * \return The projection ref (wkt string) associated with the layer */ std::string GetProjectionRef() const; @@ -496,11 +496,6 @@ public: friend bool otb::ogr::operator==(Layer const& lhs, Layer const& rhs); - /**\name Meta data dictionary */ - //@{ - itk::MetaDataDictionary & GetMetaDataDictionary(); - itk::MetaDataDictionary const& GetMetaDataDictionary() const; - //@} private: /** * Internal encapsulation of \c OGRLayer::GetNextFeature(). @@ -521,10 +516,12 @@ private: */ boost::shared_ptr<OGRLayer> m_Layer; +#if 0 /** Related DataSource. * Needed to acces OTB meta informations. */ DataSourcePtr m_DataSource; +#endif }; inline bool operator!=(Layer const& lhs, Layer const& rhs)