diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d4dea38ba39..95602088b8d 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -284,6 +284,7 @@ SET(QGIS_CORE_SRCS qgsprojectstorage.cpp qgsprojectstorageregistry.cpp qgsprojectversion.cpp + qgsprojutils.cpp qgsproperty.cpp qgspropertycollection.cpp qgspropertytransformer.cpp @@ -940,6 +941,7 @@ SET(QGIS_CORE_HDRS qgsprojectstorageregistry.h qgsprojecttranslator.h qgsprojectversion.h + qgsprojutils.h qgsproperty.h qgsproperty_p.h qgspropertycollection.h diff --git a/src/core/qgsprojutils.cpp b/src/core/qgsprojutils.cpp new file mode 100644 index 00000000000..e77e714d527 --- /dev/null +++ b/src/core/qgsprojutils.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** + qgsprojutils.h + ------------------- + begin : March 2019 + copyright : (C) 2019 by Nyall Dawson + email : nyall dot dawson at gmail dot com +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "qgsprojutils.h" + +#if PROJ_VERSION_MAJOR>=6 +#include +#else +#include +#endif + + +#ifdef USE_THREAD_LOCAL +thread_local QgsProjContext QgsProjContext::sProjContext; +#else +QThreadStorage< QgsProjContext * > QgsProjContext::sProjContext; +#endif + +QgsProjContext::QgsProjContext() +{ +#if PROJ_VERSION_MAJOR>=6 + mContext = proj_context_create(); +#else + mContext = pj_ctx_alloc(); +#endif +} + +QgsProjContext::~QgsProjContext() +{ +#if PROJ_VERSION_MAJOR>=6 + proj_context_destroy( mContext ); +#else + pj_ctx_free( mContext ); +#endif +} + +PJ_CONTEXT *QgsProjContext::get() +{ +#ifdef USE_THREAD_LOCAL + return sProjContext.mContext; +#else + PJ_CONTEXT *pContext = nullptr; + if ( sProjContext.hasLocalData() ) + { + pContext = sProjContext.localData()->mContext; + } + else + { + sProjContext.setLocalData( new QgsProjContext() ); + pContext = sProjContext.localData()->mContext; + } + return pContext; +#endif +} diff --git a/src/core/qgsprojutils.h b/src/core/qgsprojutils.h new file mode 100644 index 00000000000..6acc89d7503 --- /dev/null +++ b/src/core/qgsprojutils.h @@ -0,0 +1,69 @@ +/*************************************************************************** + qgsprojutils.h + ------------------- + begin : March 2019 + copyright : (C) 2019 by Nyall Dawson + email : nyall dot dawson at gmail dot com +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef QGSPROJUTILS_H +#define QGSPROJUTILS_H + +#include "qgis_core.h" +#include "qgsconfig.h" + +#ifndef USE_THREAD_LOCAL +#include +#endif + +#define SIP_NO_FILE + +#if PROJ_VERSION_MAJOR>=6 +struct projCtx_t; +typedef struct projCtx_t PJ_CONTEXT; +#else +typedef void PJ_CONTEXT; +#endif + +/** + * \class QgsProjContext + * \ingroup core + * Used to create and store a proj context object, correctly freeing the context upon destruction. + * \note Not available in Python bindings + */ +class CORE_EXPORT QgsProjContext +{ + public: + + QgsProjContext(); + ~QgsProjContext(); + + /** + * Returns a thread local instance of a proj context, safe for use in the current thread. + */ + static PJ_CONTEXT *get(); + + private: + PJ_CONTEXT *mContext = nullptr; + + /** + * Thread local proj context storage. A new proj context will be created + * for every thread. + */ +#ifdef USE_THREAD_LOCAL + static thread_local QgsProjContext sProjContext; +#else + static QThreadStorage< QgsProjContext * > sProjContext; +#endif +}; + + +#endif // QGSPROJUTILS_H