38
38
39
39
#ifdef USE_PROJ
40
40
static char * ms_proj_lib = NULL ;
41
+ #if PROJ_VERSION_MAJOR >= 6
42
+ static unsigned ms_proj_lib_change_counter = 0 ;
43
+ #endif
44
+
45
+ typedef struct LinkedListOfProjContext LinkedListOfProjContext ;
46
+ struct LinkedListOfProjContext
47
+ {
48
+ LinkedListOfProjContext * next ;
49
+ projectionContext * context ;
50
+ };
51
+
52
+ static LinkedListOfProjContext * headOfLinkedListOfProjContext = NULL ;
41
53
42
54
static int msTestNeedWrap ( pointObj pt1 , pointObj pt2 , pointObj pt2_geo ,
43
55
reprojectionObj * reprojector );
44
56
57
+
58
+ static projectionContext * msProjectionContextCreate (void );
59
+ static void msProjectionContextUnref (projectionContext * ctx );
60
+
45
61
#if defined(USE_PROJ ) && PROJ_VERSION_MAJOR >= 6
46
62
47
63
#include "proj_experimental.h"
@@ -69,6 +85,7 @@ typedef struct
69
85
struct projectionContext
70
86
{
71
87
PJ_CONTEXT * proj_ctx ;
88
+ unsigned ms_proj_lib_change_counter ;
72
89
int ref_count ;
73
90
pjCacheEntry pj_cache [PJ_CACHE_ENTRY_SIZE ];
74
91
int pj_cache_size ;
@@ -253,7 +270,6 @@ static void msProjErrorLogger(void * user_data,
253
270
/* msProjectionContextCreate() */
254
271
/************************************************************************/
255
272
256
- static
257
273
projectionContext * msProjectionContextCreate (void )
258
274
{
259
275
projectionContext * ctx = (projectionContext * )msSmallCalloc (1 , sizeof (projectionContext ));
@@ -265,11 +281,6 @@ projectionContext* msProjectionContextCreate(void)
265
281
}
266
282
ctx -> ref_count = 1 ;
267
283
proj_context_use_proj4_init_rules (ctx -> proj_ctx , TRUE);
268
- if ( ms_proj_lib )
269
- {
270
- const char * const paths [1 ] = { ms_proj_lib };
271
- proj_context_set_search_paths (ctx -> proj_ctx , 1 , paths );
272
- }
273
284
proj_log_func (ctx -> proj_ctx , NULL , msProjErrorLogger );
274
285
return ctx ;
275
286
}
@@ -278,7 +289,6 @@ projectionContext* msProjectionContextCreate(void)
278
289
/* msProjectionContextUnref() */
279
290
/************************************************************************/
280
291
281
- static
282
292
void msProjectionContextUnref (projectionContext * ctx )
283
293
{
284
294
if ( !ctx )
@@ -409,6 +419,24 @@ int msProjectTransformPoints( reprojectionObj* reprojector,
409
419
410
420
#else
411
421
422
+ /************************************************************************/
423
+ /* msProjectionContextCreate() */
424
+ /************************************************************************/
425
+
426
+ projectionContext * msProjectionContextCreate (void )
427
+ {
428
+ return NULL ;
429
+ }
430
+
431
+ /************************************************************************/
432
+ /* msProjectionContextUnref() */
433
+ /************************************************************************/
434
+
435
+ void msProjectionContextUnref (projectionContext * ctx )
436
+ {
437
+ (void )ctx ;
438
+ }
439
+
412
440
struct reprojectionObj
413
441
{
414
442
projectionObj * in ;
@@ -564,6 +592,25 @@ void msProjectionInheritContextFrom(projectionObj *pDst, projectionObj* pSrc)
564
592
#endif
565
593
}
566
594
595
+ /************************************************************************/
596
+ /* msProjectionSetContext() */
597
+ /************************************************************************/
598
+
599
+ void msProjectionSetContext (projectionObj * p , projectionContext * ctx )
600
+ {
601
+ #if !defined(USE_PROJ )
602
+ /* do nothing */
603
+ #elif PROJ_VERSION_MAJOR >= 6
604
+ if ( p -> proj_ctx == NULL && ctx != NULL )
605
+ {
606
+ p -> proj_ctx = ctx ;
607
+ p -> proj_ctx -> ref_count ++ ;
608
+ }
609
+ #else
610
+ /* do nothing */
611
+ #endif
612
+ }
613
+
567
614
/*
568
615
** Handle OGC WMS/WFS AUTO projection in the format:
569
616
** "AUTO:proj_id,units_id,lon0,lat0"
@@ -728,6 +775,16 @@ int msProcessProjection(projectionObj *p)
728
775
return -1 ;
729
776
}
730
777
}
778
+ if ( p -> proj_ctx -> ms_proj_lib_change_counter != ms_proj_lib_change_counter )
779
+ {
780
+ msAcquireLock ( TLOCK_PROJ );
781
+ p -> proj_ctx -> ms_proj_lib_change_counter = ms_proj_lib_change_counter ;
782
+ {
783
+ const char * const paths [1 ] = { ms_proj_lib };
784
+ proj_context_set_search_paths (p -> proj_ctx -> proj_ctx , 1 , ms_proj_lib ? paths : NULL );
785
+ }
786
+ msReleaseLock ( TLOCK_PROJ );
787
+ }
731
788
#endif
732
789
733
790
if (strncasecmp (p -> args [0 ], "AUTO:" , 5 ) == 0 ||
@@ -2259,8 +2316,21 @@ void msSetPROJ_LIB( const char *proj_lib, const char *pszRelToPath )
2259
2316
2260
2317
msAcquireLock ( TLOCK_PROJ );
2261
2318
#if PROJ_VERSION_MAJOR >= 6
2262
- free ( ms_proj_lib );
2263
- ms_proj_lib = proj_lib ? msStrdup (proj_lib ) : NULL ;
2319
+ if ( proj_lib == NULL && ms_proj_lib == NULL )
2320
+ {
2321
+ /* do nothing */
2322
+ }
2323
+ else if ( proj_lib != NULL && ms_proj_lib != NULL &&
2324
+ strcmp (proj_lib , ms_proj_lib ) == 0 )
2325
+ {
2326
+ /* do nothing */
2327
+ }
2328
+ else
2329
+ {
2330
+ ms_proj_lib_change_counter ++ ;
2331
+ free ( ms_proj_lib );
2332
+ ms_proj_lib = proj_lib ? msStrdup (proj_lib ) : NULL ;
2333
+ }
2264
2334
#else
2265
2335
{
2266
2336
static int finder_installed = 0 ;
@@ -2589,3 +2659,75 @@ int GetMapserverUnitUsingProj(projectionObj *psProj)
2589
2659
return -1 ;
2590
2660
}
2591
2661
2662
+ /************************************************************************/
2663
+ /* msProjectionContextGetFromPool() */
2664
+ /* */
2665
+ /* Returns a projection context from the pool, or create a new */
2666
+ /* one if the pool is empty. */
2667
+ /* After use, it should normally be returned with */
2668
+ /* msProjectionContextReleaseToPool() */
2669
+ /************************************************************************/
2670
+
2671
+ projectionContext * msProjectionContextGetFromPool ()
2672
+ {
2673
+ #ifdef USE_PROJ
2674
+ projectionContext * context ;
2675
+ msAcquireLock ( TLOCK_PROJ );
2676
+
2677
+ if ( headOfLinkedListOfProjContext )
2678
+ {
2679
+ LinkedListOfProjContext * next = headOfLinkedListOfProjContext -> next ;
2680
+ context = headOfLinkedListOfProjContext -> context ;
2681
+ msFree (headOfLinkedListOfProjContext );
2682
+ headOfLinkedListOfProjContext = next ;
2683
+ }
2684
+ else
2685
+ {
2686
+ context = msProjectionContextCreate ();
2687
+ }
2688
+
2689
+ msReleaseLock ( TLOCK_PROJ );
2690
+ return context ;
2691
+ #else
2692
+ return NULL ;
2693
+ #endif
2694
+ }
2695
+
2696
+ /************************************************************************/
2697
+ /* msProjectionContextReleaseToPool() */
2698
+ /************************************************************************/
2699
+
2700
+ void msProjectionContextReleaseToPool (projectionContext * ctx )
2701
+ {
2702
+ #ifdef USE_PROJ
2703
+ LinkedListOfProjContext * link =
2704
+ (LinkedListOfProjContext * )msSmallMalloc (sizeof (LinkedListOfProjContext ));
2705
+ link -> context = ctx ;
2706
+ msAcquireLock ( TLOCK_PROJ );
2707
+ link -> next = headOfLinkedListOfProjContext ;
2708
+ headOfLinkedListOfProjContext = link ;
2709
+ msReleaseLock ( TLOCK_PROJ );
2710
+ #endif
2711
+ }
2712
+
2713
+ /************************************************************************/
2714
+ /* msProjectionContextPoolCleanup() */
2715
+ /************************************************************************/
2716
+
2717
+ void msProjectionContextPoolCleanup ()
2718
+ {
2719
+ #ifdef USE_PROJ
2720
+ LinkedListOfProjContext * link ;
2721
+ msAcquireLock ( TLOCK_PROJ );
2722
+ link = headOfLinkedListOfProjContext ;
2723
+ while ( link )
2724
+ {
2725
+ LinkedListOfProjContext * next = link -> next ;
2726
+ msProjectionContextUnref (link -> context );
2727
+ msFree (link );
2728
+ link = next ;
2729
+ }
2730
+ headOfLinkedListOfProjContext = NULL ;
2731
+ msReleaseLock ( TLOCK_PROJ );
2732
+ #endif
2733
+ }
0 commit comments