@@ -691,8 +691,10 @@ int msDrawRasterLayerLow(mapObj *map, layerObj *layer, imageObj *image,
691
691
msAcquireLock ( TLOCK_GDAL );
692
692
hDS = GDALOpenShared ( decrypted_path , GA_ReadOnly );
693
693
} else {
694
+ msAcquireLock ( TLOCK_GDAL );
694
695
status = msComputeKernelDensityDataset (map , image , layer , & hDS , & kernel_density_cleanup_ptr );
695
696
if (status != MS_SUCCESS ) {
697
+ msReleaseLock ( TLOCK_GDAL );
696
698
final_status = status ;
697
699
goto cleanup ;
698
700
}
@@ -702,6 +704,8 @@ int msDrawRasterLayerLow(mapObj *map, layerObj *layer, imageObj *image,
702
704
703
705
/* Set the projection to the map file projection */
704
706
if (msLoadProjectionString (& (layer -> projection ), mapProjStr ) != 0 ) {
707
+ GDALClose ( hDS );
708
+ msReleaseLock ( TLOCK_GDAL );
705
709
msSetError (MS_CGIERR , "Unable to set projection on interpolation layer." , "msDrawRasterLayerLow()" );
706
710
return (MS_FAILURE );
707
711
}
@@ -745,6 +749,7 @@ int msDrawRasterLayerLow(mapObj *map, layerObj *layer, imageObj *image,
745
749
746
750
if ( msDrawRasterLoadProjection (layer , hDS , filename , tilesrsindex , tilesrsname ) != MS_SUCCESS )
747
751
{
752
+ GDALClose ( hDS );
748
753
msReleaseLock ( TLOCK_GDAL );
749
754
final_status = MS_FAILURE ;
750
755
break ;
@@ -792,18 +797,31 @@ int msDrawRasterLayerLow(mapObj *map, layerObj *layer, imageObj *image,
792
797
** default to keeping open for single data files, and
793
798
** to closing for tile indexes
794
799
*/
795
-
796
- close_connection = msLayerGetProcessingKey ( layer ,
800
+ if (layer -> connectiontype == MS_KERNELDENSITY ) {
801
+ /*
802
+ ** Fix issue #5330
803
+ ** The in-memory kernel density heatmap gdal dataset handle (hDS) gets re-used
804
+ ** but the associated rasterband cache doesn't get flushed, which causes old data
805
+ ** to be rendered instead of the newly generated imagery. To fix, simply close the
806
+ ** the handle and prevent further re-use.
807
+ ** Note that instead of this workaround, we could explicitely set
808
+ ** CLOSE_CONNECTION=ALWAYS on the kerneldensity layer.
809
+ */
810
+ GDALClose ( hDS );
811
+ }
812
+ else {
813
+ close_connection = msLayerGetProcessingKey ( layer ,
797
814
"CLOSE_CONNECTION" );
798
815
799
- if ( close_connection == NULL && layer -> tileindex == NULL )
800
- close_connection = "DEFER" ;
816
+ if ( close_connection == NULL && layer -> tileindex == NULL )
817
+ close_connection = "DEFER" ;
801
818
802
- if ( close_connection != NULL
803
- && strcasecmp (close_connection ,"DEFER" ) == 0 ) {
804
- GDALDereferenceDataset ( hDS );
805
- } else {
806
- GDALClose ( hDS );
819
+ if ( close_connection != NULL
820
+ && strcasecmp (close_connection ,"DEFER" ) == 0 ) {
821
+ GDALDereferenceDataset ( hDS );
822
+ } else {
823
+ GDALClose ( hDS );
824
+ }
807
825
}
808
826
msReleaseLock ( TLOCK_GDAL );
809
827
} /* next tile */
0 commit comments