47
47
typedef struct { double u, v; } projUV;
49
49
#define projPJ void *
50
#define projCtx void *
51
51
#define RAD_TO_DEG 57.29577951308232
52
52
#define DEG_TO_RAD .0174532925199432958
57
#define projCtx void *
56
62
static void *hPROJMutex = NULL;
58
64
static projPJ (*pfn_pj_init_plus)(const char *) = NULL;
59
65
static projPJ (*pfn_pj_init)(int, char**) = NULL;
60
static projUV (*pfn_pj_fwd)(projUV, projPJ) = NULL;
61
static projUV (*pfn_pj_inv)(projUV, projPJ) = NULL;
62
66
static void (*pfn_pj_free)(projPJ) = NULL;
63
67
static int (*pfn_pj_transform)(projPJ, projPJ, long, int,
64
68
double *, double *, double * ) = NULL;
67
71
static char *(*pfn_pj_get_def)(projPJ,int) = NULL;
68
72
static void (*pfn_pj_dalloc)(void *) = NULL;
74
static projPJ (*pfn_pj_init_plus_ctx)( projCtx, const char * ) = NULL;
75
static int (*pfn_pj_ctx_get_errno)( projCtx ) = NULL;
76
static projCtx (*pfn_pj_ctx_alloc)(void) = NULL;
77
static void (*pfn_pj_ctx_free)( projCtx ) = NULL;
70
79
#if (defined(WIN32) || defined(WIN32CE)) && !defined(__MINGW32__)
71
80
# define LIBNAME "proj.dll"
72
81
#elif defined(__MINGW32__)
188
214
pfn_pj_init_plus = (projPJ (*)(const char *))
189
215
CPLGetSymbol( pszLibName, "pj_init_plus" );
190
pfn_pj_fwd = (projUV (*)(projUV,projPJ))
191
CPLGetSymbol( pszLibName, "pj_fwd" );
192
pfn_pj_inv = (projUV (*)(projUV,projPJ))
193
CPLGetSymbol( pszLibName, "pj_inv" );
194
216
pfn_pj_free = (void (*)(projPJ))
195
217
CPLGetSymbol( pszLibName, "pj_free" );
196
218
pfn_pj_transform = (int (*)(projPJ,projPJ,long,int,double*,
206
228
CPLGetSymbol( pszLibName, "pj_get_def" );
207
229
pfn_pj_dalloc = (void (*)(void*))
208
230
CPLGetSymbol( pszLibName, "pj_dalloc" );
232
/* PROJ 4.8.0 symbols */
233
pfn_pj_ctx_alloc = (projCtx (*)( void ))
234
CPLGetSymbol( pszLibName, "pj_ctx_alloc" );
235
pfn_pj_ctx_free = (void (*)( projCtx ))
236
CPLGetSymbol( pszLibName, "pj_ctx_free" );
237
pfn_pj_init_plus_ctx = (projPJ (*)( projCtx, const char * ))
238
CPLGetSymbol( pszLibName, "pj_init_plus_ctx" );
239
pfn_pj_ctx_get_errno = (int (*)( projCtx ))
240
CPLGetSymbol( pszLibName, "pj_ctx_get_errno" );
209
242
CPLPopErrorHandler();
246
if (pfn_pj_ctx_alloc != NULL &&
247
pfn_pj_ctx_free != NULL &&
248
pfn_pj_init_plus_ctx != NULL &&
249
pfn_pj_ctx_get_errno != NULL &&
250
CSLTestBoolean(CPLGetConfigOption("USE_PROJ_480_FEATURES", "YES")))
252
CPLDebug("OGRCT", "PROJ >= 4.8.0 features enabled");
256
pfn_pj_ctx_alloc = NULL;
257
pfn_pj_ctx_free = NULL;
258
pfn_pj_init_plus_ctx = NULL;
259
pfn_pj_ctx_get_errno = NULL;
213
262
if( pfn_pj_transform == NULL )
215
264
CPLError( CE_Failure, CPLE_AppDefined,
359
409
/* OCTNewCoordinateTransformation() */
360
410
/************************************************************************/
413
* Create transformation object.
415
* This is the same as the C++ function OGRCreateCoordinateTransformation().
417
* Input spatial reference system objects are assigned
418
* by copy (calling clone() method) and no ownership transfer occurs.
420
* OCTDestroyCoordinateTransformation() should
421
* be used to destroy transformation objects.
423
* The PROJ.4 library must be available at run-time.
425
* @param hSourceSRS source spatial reference system.
426
* @param hTargetSRS target spatial reference system.
427
* @return NULL on failure or a ready to use transformation object.
362
430
OGRCoordinateTransformationH CPL_STDCALL
363
431
OCTNewCoordinateTransformation(
364
432
OGRSpatialReferenceH hSourceSRS, OGRSpatialReferenceH hTargetSRS )
424
525
OGRSpatialReference * poTargetIn )
530
return InitializeNoLock(poSourceIn, poTargetIn);
427
533
CPLMutexHolderD( &hPROJMutex );
534
return InitializeNoLock(poSourceIn, poTargetIn);
537
/************************************************************************/
538
/* InitializeNoLock() */
539
/************************************************************************/
541
int OGRProj4CT::InitializeNoLock( OGRSpatialReference * poSourceIn,
542
OGRSpatialReference * poTargetIn )
429
545
if( poSourceIn == NULL || poTargetIn == NULL )
542
psPJSource = pfn_pj_init_plus( pszProj4Defn );
659
psPJSource = pfn_pj_init_plus_ctx( pjctx, pszProj4Defn );
661
psPJSource = pfn_pj_init_plus( pszProj4Defn );
544
663
if( psPJSource == NULL )
546
if( pfn_pj_get_errno_ref != NULL
667
int pj_errno = pfn_pj_ctx_get_errno(pjctx);
669
/* pfn_pj_strerrno not yet thread-safe in PROJ 4.8.0 */
670
CPLMutexHolderD(&hPROJMutex);
671
CPLError( CE_Failure, CPLE_NotSupported,
672
"Failed to initialize PROJ.4 with `%s'.\n%s",
673
pszProj4Defn, pfn_pj_strerrno(pj_errno) );
675
else if( pfn_pj_get_errno_ref != NULL
547
676
&& pfn_pj_strerrno != NULL )
549
678
int *p_pj_errno = pfn_pj_get_errno_ref();
711
843
/* -------------------------------------------------------------------- */
712
844
/* Do the transformation using PROJ.4. */
713
845
/* -------------------------------------------------------------------- */
714
CPLMutexHolderD( &hPROJMutex );
848
/* The mutex has already been created */
849
CPLAssert(hPROJMutex != NULL);
850
CPLAcquireMutex(hPROJMutex, 1000.0);
716
853
if (bCheckWithInvertProj)
718
855
/* For some projections, we cannot detect if we are trying to reproject */
719
856
/* coordinates outside the validity area of the projection. So let's do */
720
857
/* the reverse reprojection and compare with the source coordinates */
722
double *ori_x = NULL;
723
double *ori_y = NULL;
724
double *ori_z = NULL;
725
ori_x = (double*)CPLMalloc(sizeof(double)*nCount);
726
memcpy(ori_x, x, sizeof(double)*nCount);
727
ori_y = (double*)CPLMalloc(sizeof(double)*nCount);
728
memcpy(ori_y, y, sizeof(double)*nCount);
858
if (nCount > nMaxCount)
861
padfOriX = (double*) CPLRealloc(padfOriX, sizeof(double)*nCount);
862
padfOriY = (double*) CPLRealloc(padfOriY, sizeof(double)*nCount);
863
padfOriZ = (double*) CPLRealloc(padfOriZ, sizeof(double)*nCount);
864
padfTargetX = (double*) CPLRealloc(padfTargetX, sizeof(double)*nCount);
865
padfTargetY = (double*) CPLRealloc(padfTargetY, sizeof(double)*nCount);
866
padfTargetZ = (double*) CPLRealloc(padfTargetZ, sizeof(double)*nCount);
868
memcpy(padfOriX, x, sizeof(double)*nCount);
869
memcpy(padfOriY, y, sizeof(double)*nCount);
731
ori_z = (double*)CPLMalloc(sizeof(double)*nCount);
732
memcpy(ori_z, z, sizeof(double)*nCount);
872
memcpy(padfOriZ, z, sizeof(double)*nCount);
734
874
err = pfn_pj_transform( psPJSource, psPJTarget, nCount, 1, x, y, z );
737
double* target_x = (double*)CPLMalloc(sizeof(double)*nCount);
738
double* target_y = (double*)CPLMalloc(sizeof(double)*nCount);
739
double* target_z = NULL;
740
memcpy(target_x, x, sizeof(double)*nCount);
741
memcpy(target_y, y, sizeof(double)*nCount);
877
memcpy(padfTargetX, x, sizeof(double)*nCount);
878
memcpy(padfTargetY, y, sizeof(double)*nCount);
744
target_z = (double*)CPLMalloc(sizeof(double)*nCount);
745
memcpy(target_z, z, sizeof(double)*nCount);
881
memcpy(padfTargetZ, z, sizeof(double)*nCount);
748
884
err = pfn_pj_transform( psPJTarget, psPJSource , nCount, 1,
749
target_x, target_y, target_z );
885
padfTargetX, padfTargetY, (z) ? padfTargetZ : NULL);
752
888
for( i = 0; i < nCount; i++ )
754
890
if ( x[i] != HUGE_VAL && y[i] != HUGE_VAL &&
755
(fabs(target_x[i] - ori_x[i]) > dfThreshold ||
756
fabs(target_y[i] - ori_y[i]) > dfThreshold) )
891
(fabs(padfTargetX[i] - padfOriX[i]) > dfThreshold ||
892
fabs(padfTargetY[i] - padfOriY[i]) > dfThreshold) )