Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

cartography: Allow ProjContext to be parallel in the event of 4.8

In 4.8, we no long share shared_ptrs. We actually make discrete
copies.
  • Loading branch information...
commit 37a466772db75f53b7a81ba8b35df4c52674b9cd 1 parent aee4aff
@zmoratto zmoratto authored
View
65 src/vw/Cartography/GeoReference.cc
@@ -36,17 +36,7 @@
#include <proj_api.h>
// Macro for checking Proj.4 output, something we do a lot of.
-#if PJ_VERSION < 480
-
-#define CHECK_PROJ_ERROR if(pj_errno) vw_throw(ProjectionErr() << "Proj.4 error: " << pj_strerrno(pj_errno))
-#define CHECK_PROJ_INIT_ERROR(str) if(pj_errno) vw_throw(InputErr() << "Proj.4 failed to initialize on string: " << str << "\n\tError was: " << pj_strerrno(pj_errno))
-
-#else
-
-#define CHECK_PROJ_ERROR if(pj_ctx_get_errno(pj_get_default_ctx())) vw_throw(ProjectionErr() << "Proj.4 error: " << pj_strerrno(pj_ctx_get_errno(pj_get_default_ctx())))
-#define CHECK_PROJ_INIT_ERROR(str) if(pj_ctx_get_errno(pj_get_default_ctx())) vw_throw(InputErr() << "Proj.4 failed to initialize on string: " << str << "\n\tError was: " << pj_strerrno(pj_ctx_get_errno(pj_get_default_ctx())))
-
-#endif
+#define CHECK_PROJ_ERROR(ctx_input) if(ctx_input.error_no()) vw_throw(ProjectionErr() << "Proj.4 error: " << pj_strerrno(ctx_input.error_no()))
namespace vw {
namespace cartography {
@@ -440,7 +430,7 @@ namespace cartography {
projected.v = loc[1];
unprojected = pj_inv(projected, m_proj_context.proj_ptr());
- CHECK_PROJ_ERROR;
+ CHECK_PROJ_ERROR( m_proj_context );
// Convert from radians to degrees.
return Vector2(unprojected.u * RAD_TO_DEG, unprojected.v * RAD_TO_DEG);
@@ -468,7 +458,7 @@ namespace cartography {
else if(unprojected.v < -BOUND) unprojected.v = -BOUND;
projected = pj_fwd(unprojected, m_proj_context.proj_ptr());
- CHECK_PROJ_ERROR;
+ CHECK_PROJ_ERROR( m_proj_context );
return Vector2(projected.u, projected.v);
}
@@ -488,20 +478,58 @@ namespace cartography {
return strings;
}
- ProjContext::ProjContext(std::string const& proj4_str) {
+#if PJ_VERSION < 480
+ ProjContext::ProjContext(std::string const& proj4_str) : m_proj4_str(proj4_str) {
// proj.4 is expecting the parameters to be split up into seperate
// c-style strings.
int num;
- char** proj_strings = split_proj4_string(proj4_str, num);
+ char** proj_strings = split_proj4_string(m_proj4_str, num);
m_proj_ptr.reset( pj_init(num, proj_strings),
pj_free );
- CHECK_PROJ_INIT_ERROR(proj4_str);
- for (int i = 0; i < num; i++)
- delete [] proj_strings[i];
+ VW_ASSERT( !pj_errno, InputErr() << "Proj.4 failed to initialize on string: " << m_proj4_str << "\n\tError was: " << pj_strerrno(pj_errno) );
+
+ for ( int i = 0; i < num; i++ ) delete [] proj_strings[i];
delete [] proj_strings;
}
+ ProjContext::ProjContext( ProjContext const& other ) : m_proj_ptr(other.m_proj_ptr), m_proj4_str(other.m_proj4_str) {}
+ ProjContext::error_no() const {
+ return pj_errno;
+ }
+#else
+ ProjContext::ProjContext(std::string const& proj4_str ) : m_proj4_str(proj4_str) {
+ m_proj_ctx_ptr.reset(pj_ctx_alloc(),pj_ctx_free);
+ int num;
+ char** proj_strings = split_proj4_string(m_proj4_str, num);
+ m_proj_ptr.reset(pj_init_ctx( m_proj_ctx_ptr.get(),
+ num, proj_strings ),
+ pj_free);
+
+ VW_ASSERT( !pj_ctx_get_errno(m_proj_ctx_ptr.get()),
+ InputErr() << "Proj.4 failed to initialize on string: " << m_proj4_str << "\n\tError was: " << pj_strerrno(pj_ctx_get_errno(m_proj_ctx_ptr.get())) );
+
+ for ( int i = 0; i < num; i++ ) delete [] proj_strings[i];
+ delete [] proj_strings;
+ }
+ ProjContext::ProjContext( ProjContext const& other ) : m_proj4_str(other.m_proj4_str) {
+ m_proj_ctx_ptr.reset(pj_ctx_alloc(),pj_ctx_free);
+ int num;
+ char** proj_strings = split_proj4_string(m_proj4_str, num);
+ m_proj_ptr.reset(pj_init_ctx( m_proj_ctx_ptr.get(),
+ num, proj_strings ),
+ pj_free);
+
+ VW_ASSERT( !pj_ctx_get_errno(m_proj_ctx_ptr.get()),
+ InputErr() << "Proj.4 failed to initialize on string: " << m_proj4_str << "\n\tError was: " << pj_strerrno(pj_ctx_get_errno(m_proj_ctx_ptr.get())) );
+
+ for ( int i = 0; i < num; i++ ) delete [] proj_strings[i];
+ delete [] proj_strings;
+ }
+ int ProjContext::error_no() const {
+ return pj_ctx_get_errno(m_proj_ctx_ptr.get());
+ }
+#endif
// Simple GeoReference modification tools
GeoReference crop( GeoReference const& input,
@@ -551,4 +579,3 @@ namespace cartography {
}} // vw::cartography
#undef CHECK_PROJ_ERROR
-#undef CHECK_PROJ_INIT_ERROR
View
25 src/vw/Cartography/GeoReference.h
@@ -39,29 +39,40 @@
// for this structure.
#if !defined(PROJECTS_H)
typedef void* projPJ;
+typedef void* projCtx;
#else
typedef PJ* projPJ;
+typedef projCtx_t *projCtx;
#endif
namespace vw {
namespace cartography {
// Here is some machinery to keep track of an initialized proj.4
- // projection context using a smart pointer. Using a smart pointer
- // here simplies the rest of the GeoReference class considerably, and
- // reduces the possibility of a memory related bug. Implementation
- // code for most of it is in GeoReference.cc.
+ // projection context using a smart pointer.
+ //
+ // Implementation of the methods to this class change based on what
+ // Proj4 version is available. So unfortunately, the methods and
+ // private variables are a mash up of what is needed for the 4.7 and
+ // 4.8 versions.
class ProjContext {
+ boost::shared_ptr<void> m_proj_ctx_ptr; // Only used for Proj4.8
boost::shared_ptr<void> m_proj_ptr;
+ std::string m_proj4_str;
char** split_proj4_string(std::string const& proj4_str, int &num_strings);
public:
- ProjContext() {};
+ ProjContext() : m_proj4_str("") {};
ProjContext(std::string const& proj4_str);
- inline projPJ proj_ptr() const { return m_proj_ptr.get(); }
+ ProjContext(ProjContext const& other ); // Only used for Proj4.8
+ inline projPJ proj_ptr() const {
+ VW_ASSERT( !m_proj4_str.empty(),
+ ArgumentErr() << "ProjContext: Projection not initialized." );
+ return m_proj_ptr.get();
+ }
+ int error_no() const;
};
-
/// The georeference class contains the mapping from image coordinates
/// (u,v) to geospatial coordinates (typically lat/lon, or possibly
/// meters in a UTM grid cell, etc.)
View
18 src/vw/Cartography/GeoTransform.cc
@@ -26,17 +26,7 @@
#include <proj_api.h>
// Macro for checking Proj.4 output, something we do a lot of.
-#if PJ_VERSION < 480
-
-#define CHECK_PROJ_ERROR if(pj_errno) vw_throw(ProjectionErr() << "Proj.4 error: " << pj_strerrno(pj_errno))
-#define CHECK_PROJ_INIT_ERROR(str) if(pj_errno) vw_throw(InputErr() << "Proj.4 failed to initialize on string: " << str << "\n\tError was: " << pj_strerrno(pj_errno))
-
-#else
-
-#define CHECK_PROJ_ERROR if(pj_ctx_get_errno(pj_get_default_ctx())) vw_throw(ProjectionErr() << "Proj.4 error: " << pj_strerrno(pj_ctx_get_errno(pj_get_default_ctx())))
-#define CHECK_PROJ_INIT_ERROR(str) if(pj_ctx_get_errno(pj_get_default_ctx())) vw_throw(InputErr() << "Proj.4 failed to initialize on string: " << str << "\n\tError was: " << pj_strerrno(pj_ctx_get_errno(pj_get_default_ctx())))
-
-#endif
+#define CHECK_PROJ_ERROR(ctx_input) if(ctx_input.error_no()) vw_throw(ProjectionErr() << "Proj.4 error: " << pj_strerrno(ctx_input.error_no()))
namespace vw {
namespace cartography {
@@ -72,13 +62,11 @@ namespace cartography {
// source or destination georef uses.
ss_src << "+proj=latlong " << src_datum;
m_src_proj = ProjContext( ss_src.str() );
- CHECK_PROJ_INIT_ERROR( ss_src.str() );
// The destination proj4 context.
std::stringstream ss_dst;
ss_dst << "+proj=latlong " << dst_datum;
m_dst_proj = ProjContext( ss_dst.str() );
- CHECK_PROJ_INIT_ERROR( ss_dst.str() );
}
// Because GeoTransform is typically very slow, we default to a tolerance
// of 0.1 pixels to allow ourselves to be approximated.
@@ -95,7 +83,8 @@ namespace cartography {
pj_transform(m_src_proj.proj_ptr(), m_dst_proj.proj_ptr(), 1, 0, &x, &y, &z);
else
pj_transform(m_dst_proj.proj_ptr(), m_src_proj.proj_ptr(), 1, 0, &x, &y, &z);
- CHECK_PROJ_ERROR;
+ CHECK_PROJ_ERROR( m_src_proj );
+ CHECK_PROJ_ERROR( m_dst_proj );
return Vector2(x, y);
}
@@ -165,4 +154,3 @@ namespace cartography {
}} // namespace vw::cartography
#undef CHECK_PROJ_ERROR
-#undef CHECK_PROJ_INIT_ERROR
Please sign in to comment.
Something went wrong with that request. Please try again.