Commit d93c8680 authored by Luc Hermitte's avatar Luc Hermitte

REFAC: little optimizations in Get(Global)Extent

parent 8050e145
......@@ -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;
......
......@@ -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,
......
......@@ -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)*/);
}
......
......@@ -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();
}
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment