[gdal] 03/10: New upstream version 2.2.4~rc1+dfsg

Bas Couwenberg sebastic at debian.org
Mon Mar 19 18:28:24 UTC 2018


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch experimental
in repository gdal.

commit b103f2c06f9b1456af933bd37a08d269872128d4
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Mon Mar 19 15:28:00 2018 +0100

    New upstream version 2.2.4~rc1+dfsg
---
 GDALmake.opt.in                                  |   2 +-
 NEWS                                             | 113 ++++++-
 VERSION                                          |   2 +-
 alg/gdalwarpoperation.cpp                        |   4 +-
 alg/llrasterize.cpp                              |   6 +-
 alg/thinplatespline.cpp                          |  10 +-
 apps/gdalinfo_lib.cpp                            |  22 +-
 apps/gdalwarp_lib.cpp                            |  20 +-
 apps/ogr2ogr_lib.cpp                             |  27 +-
 ci/travis/precise_clang/script.sh                |   2 +
 ci/travis/python3/script.sh                      |   1 +
 configure                                        |  66 ++++-
 configure.ac                                     |  65 +++-
 frmts/airsar/airsardataset.cpp                   |   4 +-
 frmts/gtiff/geotiff.cpp                          |  18 +-
 frmts/netcdf/netcdfdataset.cpp                   | 359 ++++++++++++++---------
 frmts/nitf/nitfimage.c                           |  12 +-
 frmts/pcraster/GNUmakefile                       |   2 +-
 frmts/pcraster/libcsf/README                     |   5 +-
 frmts/pcraster/libcsf/_gsomece.c                 |   2 +-
 frmts/pcraster/libcsf/attrsize.c                 |   1 +
 frmts/pcraster/libcsf/create2.c                  |   4 +-
 frmts/pcraster/libcsf/csf.h                      |   7 +-
 frmts/pcraster/libcsf/csfimpl.h                  |   7 +
 frmts/pcraster/libcsf/file.c                     |  26 ++
 frmts/pcraster/libcsf/getattr.c                  |   2 +-
 frmts/pcraster/libcsf/legend.c                   |   2 +-
 frmts/pcraster/libcsf/makefile.vc                |   2 +-
 frmts/pcraster/libcsf/mclose.c                   |   4 +-
 frmts/pcraster/libcsf/mopen.c                    |  10 +-
 frmts/pcraster/libcsf/putattr.c                  |  14 +-
 frmts/pcraster/libcsf/putsomec.c                 |   2 +-
 frmts/pcraster/libcsf/rattrblk.c                 |   2 +-
 frmts/pcraster/libcsf/ruseas.c                   |   1 +
 frmts/pcraster/libcsf/wattrblk.c                 |   2 +-
 frmts/raw/ehdrdataset.cpp                        |  30 +-
 frmts/raw/rrasterdataset.cpp                     |   8 +-
 frmts/sentinel2/sentinel2dataset.cpp             |   6 +-
 frmts/vrt/vrtderivedrasterband.cpp               |  15 +-
 frmts/vrt/vrtrasterband.cpp                      |   4 +-
 gcore/gdal_version.h                             |   8 +-
 gnm/gnm_frmts/file/gnmfilenetwork.cpp            |   8 +-
 man/man1/gdal-config.1                           |   2 +-
 man/man1/gdal2tiles.1                            |   2 +-
 man/man1/gdal_calc.1                             |   2 +-
 man/man1/gdal_contour.1                          |   2 +-
 man/man1/gdal_edit.1                             |   2 +-
 man/man1/gdal_fillnodata.1                       |   2 +-
 man/man1/gdal_grid.1                             |   2 +-
 man/man1/gdal_merge.1                            |   2 +-
 man/man1/gdal_pansharpen.1                       |   2 +-
 man/man1/gdal_polygonize.1                       |   2 +-
 man/man1/gdal_proximity.1                        |   2 +-
 man/man1/gdal_rasterize.1                        |   2 +-
 man/man1/gdal_retile.1                           |   2 +-
 man/man1/gdal_sieve.1                            |   2 +-
 man/man1/gdal_translate.1                        |   2 +-
 man/man1/gdal_utilities.1                        |   2 +-
 man/man1/gdaladdo.1                              |   2 +-
 man/man1/gdalbuildvrt.1                          |   2 +-
 man/man1/gdalcompare.1                           |   2 +-
 man/man1/gdaldem.1                               |   2 +-
 man/man1/gdalinfo.1                              |   2 +-
 man/man1/gdallocationinfo.1                      |   2 +-
 man/man1/gdalmanage.1                            |   2 +-
 man/man1/gdalmove.1                              |   2 +-
 man/man1/gdalsrsinfo.1                           |   2 +-
 man/man1/gdaltindex.1                            |   2 +-
 man/man1/gdaltransform.1                         |   2 +-
 man/man1/gdalwarp.1                              |   2 +-
 man/man1/gnm_utilities.1                         |   2 +-
 man/man1/gnmanalyse.1                            |   2 +-
 man/man1/gnmmanage.1                             |   2 +-
 man/man1/nearblack.1                             |   2 +-
 man/man1/ogr2ogr.1                               |   2 +-
 man/man1/ogr_utilities.1                         |   2 +-
 man/man1/ogrinfo.1                               |   2 +-
 man/man1/ogrlineref.1                            |   2 +-
 man/man1/ogrmerge.1                              |   2 +-
 man/man1/ogrtindex.1                             |   2 +-
 man/man1/pct2rgb.1                               |   2 +-
 man/man1/rgb2pct.1                               |   2 +-
 ogr/ogrct.cpp                                    |   6 +-
 ogr/ogrgeometry.cpp                              |   4 +-
 ogr/ogrsf_frmts/carto/ogr_carto.h                |  11 +-
 ogr/ogrsf_frmts/carto/ogrcartolayer.cpp          |  16 +-
 ogr/ogrsf_frmts/carto/ogrcartotablelayer.cpp     |  87 +++---
 ogr/ogrsf_frmts/geojson/ogrgeojsonwritelayer.cpp |   3 +-
 ogr/ogrsf_frmts/geojson/ogrgeojsonwriter.cpp     |  32 +-
 ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp |   6 +-
 ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp   |  42 ++-
 ogr/ogrsf_frmts/mitab/mitab_spatialref.cpp       |   3 +-
 ogr/ogrsf_frmts/mitab/mitab_tabview.cpp          |   3 +-
 ogr/ogrsf_frmts/nas/nashandler.cpp               |  16 +-
 ogr/ogrsf_frmts/ntf/ntffilereader.cpp            |   4 +-
 ogr/ogrsf_frmts/odbc/ogrodbctablelayer.cpp       |  38 ++-
 ogr/ogrsf_frmts/shape/dbfopen.c                  |  34 ++-
 ogr/ogrsf_frmts/shape/shpopen.c                  |  81 ++---
 ogr/ogrsf_frmts/xlsx/ogrxlsxdatasource.cpp       |  18 +-
 port/cpl_error.cpp                               |  35 +--
 swig/include/Dataset.i                           |  10 +-
 swig/include/perl/gdal_perl.i                    |   4 +-
 swig/include/perl/ogr_perl.i                     |   2 +-
 swig/include/python/gdal_python.i                |  10 +-
 swig/perl/gdal_wrap.cpp                          |   8 +-
 swig/perl/lib/Geo/GDAL.pm                        |   4 +-
 swig/perl/lib/Geo/OGR.pm                         |   2 +-
 swig/python/README.txt                           |   2 +-
 swig/python/extensions/gdal_wrap.cpp             |   4 +-
 swig/python/osgeo/gdal.py                        |   8 +
 swig/python/setup.py                             |   5 +-
 111 files changed, 1009 insertions(+), 476 deletions(-)

diff --git a/GDALmake.opt.in b/GDALmake.opt.in
index 4b16a9a..c7d4128 100644
--- a/GDALmake.opt.in
+++ b/GDALmake.opt.in
@@ -120,7 +120,7 @@ GDAL_INCLUDE	=	-I$(GDAL_ROOT)/port -I$(GDAL_ROOT)/gcore \
 # libtool targets and help variables
 LIBGDAL	:=		libgdal.la
 LIBGDAL_CURRENT	:=	23
-LIBGDAL_REVISION	:=	2
+LIBGDAL_REVISION	:=	3
 LIBGDAL_AGE	:=	3
 
 # native build targets and variables
diff --git a/NEWS b/NEWS
index ae3709c..b028d44 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,114 @@
+= GDAL/OGR 2.2.4 Release Notes = 
+
+The 2.2.4 release is a bug fix release.
+
+== Build ==
+
+ * configure: add support for ECW SDK 5.4, by detecting if we must link against the newabi or oldabi link
+
+== Port ==
+
+ * CPLSetErrorHandler(): avoid later crashes when passing a null callback (https://github.com/OSGeo/gdal/pull/298)
+
+== GDAL utilities ==
+
+ * gdalinfo: make sure to display geodetic coordinates always in degree (and not potentially in another unit such as grad) (#4198)
+ * gdalinfo / VRT: fix crash with implicit overviews on per-dataset mask band (https://github.com/mapbox/rasterio/issues/1266#issuecomment-367233149)
+ * gdalwarp: fix when several input datasets with different SRS are specified, and no explicit target SRS is provided (#7170)
+ * gdal_rasterize: fix crash in some situations with ALL_TOUCHED option (#7176)
+
+== GDAL algorithms ==
+
+ * Warping: use panSrcBands[0] in the single band case (regression fix, https://github.com/OSGeo/gdal/pull/295)
+
+== GDAL drivers ==
+
+AirSAR driver:
+ * fix computation of imaginary part in C23 case (#7222)
+
+EHdr driver:
+ * fix read heap buffer overflow with nbits < 8. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6724. Credit to OSS Fuzz
+
+GTiff driver:
+ * use consistently multiplication/division by 257 when converting between GDAL [0,255] range to TIFF [0,65535] range for color map values (#2213)
+
+netCDF driver:
+ * behave correctly when an extra dimension of a variable has a corresponding 1D variable of different names (#7165)
+
+NITF driver:
+ * fix swapped lines and samples in IMRFCA (https://github.com/OSGeo/gdal/pull/289)
+
+PCRaster driver:
+ * fix fseek/ftell for large files on Windows (#7255)
+
+RRASTER driver:
+ * fix wrong declaration of PIXELTYPE=SIGNEDBYTE for datatype=INT1S
+ * fix reading empty nodatavalue keyword
+
+Sentinel2 driver:
+ * make sure that the True Color Image subdatset really uses the R,G,B bands and not the R,R,R (#7251)
+
+VRT driver:
+ * VRTDerivedRasterBand: fix detection of Python runtime already loaded when more than 100 modules are linked. Fixes QGIS3 use case (#7213)
+
+== OGR core ==
+
+ * Fixed memory leak in OGRPolygon::PointOnSurface method (https://github.com/OSGeo/gdal/pull/269)
+ * OGRCT: make sure to free the proj4 context after freeing the projection objects, to avoid crashes
+
+== OGR utilities ==
+
+ * ogr2ogr: honour -select when using -addfiels; fix converting from Memory to Memory datasources (#7217)
+
+== OGR drivers ==
+
+Carto driver:
+ * fix append mode by retrieving the sequence name for the primary key (#7203)
+ * fix insertion with ogr2ogr -preserve_fid (#7216)
+ * fix missing features when iterating over a SQL result layer with pagination (#6880)
+
+GeoJSON driver:
+ * fix writing of id with RFC7946=YES (#7194)
+ * Add support for json-c v0.13 (#7195)
+
+GPKG driver:
+ * fix incorrect rtree_<t>_<c>_update3 trigger statement, as found in https://github.com/opengeospatial/geopackage/issues/414
+
+LIBKML driver:
+ * workaround Windows specific issue with libkml (at least the version used by OSGeo4W at time of writing), where tabulations as coordinate separators aren't properly handled (#7231)
+ * workaround Windows specific issue if the content of <coordinates> is non-empty and does not contain any digit (#7232)
+
+MITAB driver:
+ * fix crash on reading TAB views (#7171)
+ * add support for SWEREF99 datum (#7256)
+
+NAS driver:
+ * also accept unqualified attribute name in wfs:Update
+ * fix memory leak and potential assertion. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2661. Credit to OSS Fuzz
+
+NTF driver: 
+ * fix regression introduced by fix for https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2166 causing some valid records to be skipped (#7204)
+
+Shapefile driver:
+ * fix write heap buffer overflow when provided with empty string filename. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6992. Credit to OSS Fuzz
+ * fix potential read heap buffer overflow in single-point polygon in SHPRewindObject(). Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6993. Credit to OSS Fuzz
+
+ODBC driver:
+ * deal with table names that require double quoting (#7242)
+
+XLSX driver:
+ * fix updating multi layer document where existing layers where dropped (#7225)
+ * on writing, use %.16g formatting for floating point numbers (#7230)
+
+== GNM ==
+ * avoid potential issue with CPL circular buffers (can happen if there are extra drivers that use CPLGet....() functions)
+
+== SWIG bindings ==
+
+ * Fix potential null pointer dereference in Python/Perl Dataset.WriteRaster() and Perl Dataset.ReadRaster() when buffer type is not specified and there is a single band
+ * Python bindings: add addFields and forceNullable options to gdal.VectorTranslate() (#7217)
+ * Python bindings: fix build when CC variable is made of serveral words
+
 = GDAL/OGR 2.2.3 Release Notes = 
 
 The 2.2.3 release is a bug fix release.
@@ -113,8 +224,6 @@ GPKG driver:
 GTM driver:
  * fix null pointer dereference in case of read error (https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4047)
 
-KML / LIBKML drivers:
-
 MDB driver:
  * fix multi-thread support (https://issues.qgis.org/issues/16039)
 
diff --git a/VERSION b/VERSION
index 5859406..530cdd9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.3
+2.2.4
diff --git a/alg/gdalwarpoperation.cpp b/alg/gdalwarpoperation.cpp
index 703fc7a..5e7ef41 100644
--- a/alg/gdalwarpoperation.cpp
+++ b/alg/gdalwarpoperation.cpp
@@ -49,7 +49,7 @@
 #include "ogr_api.h"
 #include "ogr_core.h"
 
-CPL_CVSID("$Id: gdalwarpoperation.cpp 39828 2017-08-16 08:07:41Z rouault $");
+CPL_CVSID("$Id: gdalwarpoperation.cpp 41328 2018-01-24 21:57:56Z rouault $");
 
 struct _GDALWarpChunk {
     int dx, dy, dsx, dsy;
@@ -1776,7 +1776,7 @@ CPLErr GDALWarpOperation::WarpRegionToBuffer(
         if( psOptions->nBandCount == 1 )
         {
             // Particular case to simplify the stack a bit.
-            eErr = poSrcDS->GetRasterBand(psOptions->panDstBands[0])->RasterIO(
+            eErr = poSrcDS->GetRasterBand(psOptions->panSrcBands[0])->RasterIO(
                                   GF_Read,
                                   nSrcXOff, nSrcYOff, nSrcXSize, nSrcYSize,
                                   oWK.papabySrcImage[0], nSrcXSize, nSrcYSize,
diff --git a/alg/llrasterize.cpp b/alg/llrasterize.cpp
index 416509d..bbcebed 100644
--- a/alg/llrasterize.cpp
+++ b/alg/llrasterize.cpp
@@ -39,7 +39,7 @@
 
 #include "gdal_alg.h"
 
-CPL_CVSID("$Id: llrasterize.cpp 38818 2017-06-02 12:08:07Z rouault $");
+CPL_CVSID("$Id: llrasterize.cpp 41013 2017-12-12 12:05:53Z rouault $");
 
 static int llCompareInt(const void *a, const void *b)
 {
@@ -452,7 +452,7 @@ GDALdllImageLineAllTouched( int nRasterXSize, int nRasterYSize,
                 int iY = static_cast<int>(floor(dfY));
                 int iYEnd = (int) floor(dfYEnd);
 
-                if( iX >= nRasterXSize )
+                if( iX < 0 || iX >= nRasterXSize )
                     continue;
 
                 double dfDeltaVariant = 0.0;
@@ -495,7 +495,7 @@ GDALdllImageLineAllTouched( int nRasterXSize, int nRasterYSize,
                 const int iY = static_cast<int>(floor(dfY));
                 int iXEnd = (int) floor(dfXEnd);
 
-                if( iY >= nRasterYSize )
+                if( iY < 0 || iY >= nRasterYSize )
                     continue;
 
                 // Clip to the borders of the target region.
diff --git a/alg/thinplatespline.cpp b/alg/thinplatespline.cpp
index 0004e57..2ce05e7 100644
--- a/alg/thinplatespline.cpp
+++ b/alg/thinplatespline.cpp
@@ -57,7 +57,7 @@
 #include "cpl_error.h"
 #include "cpl_vsi.h"
 
-CPL_CVSID("$Id: thinplatespline.cpp 37119 2017-01-12 12:22:02Z rouault $");
+CPL_CVSID("$Id: thinplatespline.cpp 41859 2018-03-17 23:39:06Z rouault $");
 
 //////////////////////////////////////////////////////////////////////////////
 //// vizGeorefSpline2D
@@ -435,13 +435,13 @@ static void VizGeorefSpline2DBase_func4( double* res,
                                          const double* xr, const double* yr )
 {
     double dist0  = SQ( xr[0] - pxy[0] ) + SQ( yr[0] - pxy[1] );
-    res[0] = dist0 ? dist0 * log(dist0) : 0.0;
+    res[0] = dist0 != 0.0 ? dist0 * log(dist0) : 0.0;
     double dist1  = SQ( xr[1] - pxy[0] ) + SQ( yr[1] - pxy[1] );
-    res[1] = dist1 ? dist1 * log(dist1) : 0.0;
+    res[1] = dist1 != 0.0 ? dist1 * log(dist1) : 0.0;
     double dist2  = SQ( xr[2] - pxy[0] ) + SQ( yr[2] - pxy[1] );
-    res[2] = dist2 ? dist2 * log(dist2) : 0.0;
+    res[2] = dist2 != 0.0 ? dist2 * log(dist2) : 0.0;
     double dist3  = SQ( xr[3] - pxy[0] ) + SQ( yr[3] - pxy[1] );
-    res[3] = dist3 ? dist3 * log(dist3) : 0.0;
+    res[3] = dist3 != 0.0 ? dist3 * log(dist3) : 0.0;
 }
 #endif // defined(USE_OPTIMIZED_VizGeorefSpline2DBase_func4)
 
diff --git a/apps/gdalinfo_lib.cpp b/apps/gdalinfo_lib.cpp
index 9c7d262..185a63a 100644
--- a/apps/gdalinfo_lib.cpp
+++ b/apps/gdalinfo_lib.cpp
@@ -55,12 +55,13 @@
 #include "ogr_api.h"
 #include "ogr_json_header.h"
 #include "ogr_srs_api.h"
+#include "ogr_spatialref.h"
 #include "ogrgeojsonreader.h"
 #include "ogrgeojsonwriter.h"
 
 using std::vector;
 
-CPL_CVSID("$Id: gdalinfo_lib.cpp 38115 2017-04-23 07:24:41Z rouault $");
+CPL_CVSID("$Id: gdalinfo_lib.cpp 41753 2018-03-12 15:58:55Z rouault $");
 
 /*! output format */
 typedef enum {
@@ -591,6 +592,20 @@ char *GDALInfo( GDALDatasetH hDataset, const GDALInfoOptions *psOptions )
             else
             {
                 hLatLong = OSRCloneGeogCS( hProj );
+                if( hLatLong )
+                {
+                    // Drop GEOGCS|UNIT child to be sure to output as degrees
+                    OGRSpatialReference* poLatLong = reinterpret_cast<
+                        OGRSpatialReference*>(hLatLong);
+                    OGR_SRSNode *poGEOGCS = poLatLong->GetRoot();
+                    if( poGEOGCS )
+                    {
+                        const int iUnitChild =
+                            poGEOGCS->FindChild("UNIT");
+                        if( iUnitChild != -1 )
+                            poGEOGCS->DestroyChild(iUnitChild);
+                    }
+                }
             }
         }
 
@@ -1181,7 +1196,9 @@ char *GDALInfo( GDALDatasetH hDataset, const GDALInfoOptions *psOptions )
                      iOverview < GDALGetOverviewCount(hMaskBand);
                      iOverview++ )
                 {
-                    GDALRasterBandH hOverview;
+                    GDALRasterBandH hOverview = GDALGetOverview( hMaskBand, iOverview );
+                    if( !hOverview )
+                        break;
                     json_object *poMaskOverview = NULL;
                     json_object *poMaskOverviewSize = NULL;
 
@@ -1196,7 +1213,6 @@ char *GDALInfo( GDALDatasetH hDataset, const GDALInfoOptions *psOptions )
                             Concat(osStr, psOptions->bStdoutOutput, ", " );
                     }
 
-                    hOverview = GDALGetOverview( hMaskBand, iOverview );
                     if(bJson)
                     {
                         json_object *poMaskOverviewSizeX =
diff --git a/apps/gdalwarp_lib.cpp b/apps/gdalwarp_lib.cpp
index fc5c8b7..bb013e0 100644
--- a/apps/gdalwarp_lib.cpp
+++ b/apps/gdalwarp_lib.cpp
@@ -59,7 +59,7 @@
 #include "ogr_srs_api.h"
 #include "vrtdataset.h"
 
-CPL_CVSID("$Id: gdalwarp_lib.cpp 40601 2017-11-01 10:47:26Z rouault $");
+CPL_CVSID("$Id: gdalwarp_lib.cpp 40943 2017-12-04 13:20:48Z rouault $");
 
 /************************************************************************/
 /*                        GDALWarpAppOptions                            */
@@ -2012,6 +2012,8 @@ GDALWarpCreateOutput( int nSrcCount, GDALDatasetH *pahSrcDS, const char *pszFile
             osThisTargetSRS = pszThisTargetSRS;
     }
 
+    CPLStringList aoTOList(papszTO, FALSE);
+
     for( iSrc = 0; iSrc < nSrcCount; iSrc++ )
     {
         const char *pszThisSourceSRS = CSLFetchNameValue(papszTO,"SRC_SRS");
@@ -2062,9 +2064,10 @@ GDALWarpCreateOutput( int nSrcCount, GDALDatasetH *pahSrcDS, const char *pszFile
         }
 
 /* -------------------------------------------------------------------- */
-/*      Get the sourcesrs from the dataset, if not set already.         */
+/*      If we are processing the first file, get the source srs from    */
+/*      dataset, if not set already.                                    */
 /* -------------------------------------------------------------------- */
-        if( pszThisSourceSRS == NULL )
+        if( iSrc == 0 && osThisTargetSRS.empty() )
         {
             const char *pszMethod = CSLFetchNameValue( papszTO, "METHOD" );
 
@@ -2082,17 +2085,20 @@ GDALWarpCreateOutput( int nSrcCount, GDALDatasetH *pahSrcDS, const char *pszFile
                 pszThisSourceSRS = SRS_WKT_WGS84;
             else
                 pszThisSourceSRS = "";
-        }
 
-        if( osThisTargetSRS.empty() )
-            osThisTargetSRS = pszThisSourceSRS;
+            if( pszThisSourceSRS != NULL && pszThisSourceSRS[0] != '\0' )
+            {
+                osThisTargetSRS = pszThisSourceSRS;
+                aoTOList.SetNameValue("DST_SRS", pszThisSourceSRS);
+            }
+        }
 
 /* -------------------------------------------------------------------- */
 /*      Create a transformation object from the source to               */
 /*      destination coordinate system.                                  */
 /* -------------------------------------------------------------------- */
         hTransformArg =
-            GDALCreateGenImgProjTransformer2( pahSrcDS[iSrc], NULL, papszTO );
+            GDALCreateGenImgProjTransformer2( pahSrcDS[iSrc], NULL, aoTOList.List() );
 
         if( hTransformArg == NULL )
         {
diff --git a/apps/ogr2ogr_lib.cpp b/apps/ogr2ogr_lib.cpp
index aea8a88..56bd8a1 100644
--- a/apps/ogr2ogr_lib.cpp
+++ b/apps/ogr2ogr_lib.cpp
@@ -61,7 +61,7 @@
 #include "ogrlayerdecorator.h"
 #include "ogrsf_frmts.h"
 
-CPL_CVSID("$Id: ogr2ogr_lib.cpp 39771 2017-08-07 19:33:50Z rouault $");
+CPL_CVSID("$Id: ogr2ogr_lib.cpp 41373 2018-02-01 10:09:27Z rouault $");
 
 typedef enum
 {
@@ -2057,6 +2057,7 @@ GDALDatasetH GDALVectorTranslate( const char *pszDest, GDALDatasetH hDstDS, int
     /* Various tests to avoid overwriting the source layer(s) */
     /* or to avoid appending a layer to itself */
     if( bUpdate && strcmp(osDestFilename, poDS->GetDescription()) == 0 &&
+        !EQUAL(poDS->GetDriverName(), "Memory") &&
         (bOverwrite || bAppend) )
     {
         bool bError = false;
@@ -3865,8 +3866,30 @@ TargetLayerInfo* SetupTargetLayer::Setup(OGRLayer* poSrcLayer,
 
         const char* pszFIDColumn = poDstLayer->GetFIDColumn();
 
-        for( int iField = 0; iField < nSrcFieldCount; iField++ )
+        std::vector<int> anSrcFieldIndices;
+        if( m_papszSelFields )
+        {
+            for( int iField=0; m_papszSelFields[iField] != NULL; iField++)
+            {
+                const int iSrcField =
+                    poSrcFDefn->GetFieldIndex(m_papszSelFields[iField]);
+                if (iSrcField >= 0)
+                {
+                    anSrcFieldIndices.push_back(iSrcField);
+                }
+            }
+        }
+        else
+        {
+            for( int iField = 0; iField < nSrcFieldCount; iField++ )
+            {
+                anSrcFieldIndices.push_back(iField);
+            }
+        }
+
+        for( size_t i = 0; i < anSrcFieldIndices.size(); i++ )
         {
+            const int iField = anSrcFieldIndices[i];
             OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iField);
             OGRFieldDefn oFieldDefn( poSrcFieldDefn );
 
diff --git a/ci/travis/precise_clang/script.sh b/ci/travis/precise_clang/script.sh
index a754f8f..765d2d1 100755
--- a/ci/travis/precise_clang/script.sh
+++ b/ci/travis/precise_clang/script.sh
@@ -38,6 +38,7 @@ cd ..
 cd ogr
 python ogr_pgeo.py
 mv ogr_pgeo.* disabled
+mv ogr_mongodb.* disabled
 cd ..
 # Run all the Python autotests
 GDAL_SKIP="JP2ECW ECW" python run_all.py
@@ -51,6 +52,7 @@ cd ..
 
 git checkout ogr/ogr_fgdb.py
 git checkout ogr/ogr_pgeo.py
+git checkout ogr/ogr_mongodb.py
 if test `git diff | wc -l` != "0"; then
     echo "Files have been modified duing testsuite run:"
     git diff
diff --git a/ci/travis/python3/script.sh b/ci/travis/python3/script.sh
index 8e408bb..b6b9da1 100755
--- a/ci/travis/python3/script.sh
+++ b/ci/travis/python3/script.sh
@@ -37,6 +37,7 @@ cd ..
 cd ogr
 python3 ogr_pgeo.py
 mv ogr_pgeo.* disabled
+mv ogr_mongodb.* disabled
 cd ..
 # Run all the Python autotests
 GDAL_SKIP="JP2ECW ECW" python3 run_all.py
diff --git a/configure b/configure
index 8796854..536a79e 100755
--- a/configure
+++ b/configure
@@ -25561,6 +25561,7 @@ FGDB_INC=$FGDB_INC
 ECW_FLAGS=
 ECW_LIBS=
 ECW_INCLUDE=
+ECW_54=
 
 
 # Check whether --with-ecw was given.
@@ -25715,21 +25716,63 @@ $as_echo "found libecwj2 in $with_ecw/lib." >&6; }
 
   # ECW SDK 5.0 style and also for the case where license type is included in path i.e. specific license type is requested.
   elif test -r $with_ecw/lib/$ECW_ARCH/$ECW_CONF/libNCSEcw.a ; then
-    ECW_LIBDIR=$with_ecw/lib/$ECW_ARCH/$ECW_CONF
-    ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found Intergraph 5.x+ SDK in ${ECW_LIBDIR}." >&5
+    # Test if we must use the newabi version (SDK 5.4)
+    if test -r $with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then
+        echo "#include <string>" > testnewabi.cpp
+        echo "namespace NCS { class CString { public: static std::wstring Utf8Decode (const std::string &sUtf8); }; }" >> testnewabi.cpp
+        echo "int main() { return static_cast<int>(NCS::CString::Utf8Decode(std::string()).size()); }" >> testnewabi.cpp
+        if test -z "`${CXX} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then
+            ECW_LIBDIR=$with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF
+            ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
+            with_ecw=$with_ecw/$ecw_license_type
+            ECW_54="yes"
+            { $as_echo "$as_me:${as_lineno-$LINENO}: result: found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}." >&5
+$as_echo "found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}." >&6; }
+            rm -f testnewabi.*
+            rm -f testnewabi
+            break
+        fi
+        rm -f testnewabi.*
+        rm -f testnewabi
+    fi
+    if test "$ECW_LIBS" = ""; then
+        ECW_LIBDIR=$with_ecw/lib/$ECW_ARCH/$ECW_CONF
+        ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: found Intergraph 5.x+ SDK in ${ECW_LIBDIR}." >&5
 $as_echo "found Intergraph 5.x+ SDK in ${ECW_LIBDIR}." >&6; }
+    fi
  # ECWJP2 SDK 5.1 style
   elif test -d $with_ecw; then
     for ecw_license_type in "Desktop_Read-Write" "Server_Read-Only_EndUser" "Server_Read-Only" "Server_Read-Write" "Desktop_Read-Only"
       do
-        ECW_LIBDIR=$with_ecw/$ecw_license_type/lib/$ECW_ARCH/$ECW_CONF
-        if test -r $ECW_LIBDIR/libNCSEcw.a; then
-          ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
-          with_ecw=$with_ecw/$ecw_license_type
-          { $as_echo "$as_me:${as_lineno-$LINENO}: result: found Intergraph 5.x+ SDK in ${ECW_LIBDIR}." >&5
+        # Test if we must use the newabi version (SDK 5.4)
+        if test -r $with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then
+            echo "#include <string>" > testnewabi.cpp
+            echo "namespace NCS { class CString { public: static std::wstring Utf8Decode (const std::string &sUtf8); }; }" >> testnewabi.cpp
+            echo "int main() { return static_cast<int>(NCS::CString::Utf8Decode(std::string()).size()); }" >> testnewabi.cpp
+            if test -z "`${CXX} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then
+                ECW_LIBDIR=$with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF
+                ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
+                with_ecw=$with_ecw/$ecw_license_type
+                { $as_echo "$as_me:${as_lineno-$LINENO}: result: found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}." >&5
+$as_echo "found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}." >&6; }
+                ECW_54="yes"
+                rm -f testnewabi.*
+                rm -f testnewabi
+                break
+            fi
+            rm -f testnewabi.*
+            rm -f testnewabi
+        fi
+        if test "$ECW_LIBS" = ""; then
+            ECW_LIBDIR=$with_ecw/$ecw_license_type/lib/$ECW_ARCH/$ECW_CONF
+            if test -r $ECW_LIBDIR/libNCSEcw.a; then
+                ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
+                with_ecw=$with_ecw/$ecw_license_type
+                { $as_echo "$as_me:${as_lineno-$LINENO}: result: found Intergraph 5.x+ SDK in ${ECW_LIBDIR}." >&5
 $as_echo "found Intergraph 5.x+ SDK in ${ECW_LIBDIR}." >&6; }
-          break
+                break
+            fi
         fi
       done
  else
@@ -36854,3 +36897,8 @@ if test "$PROJ_STATIC" = "no" -a "$FGDB_ENABLED" = "yes" -a "$FGDB_HAS_PROJ4" =
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --without-static-proj and --with-fgdb are both available. There might be some incompatibility between system libproj and the embedded copy within libFileGDBAPI" >&5
 $as_echo "$as_me: WARNING: --without-static-proj and --with-fgdb are both available. There might be some incompatibility between system libproj and the embedded copy within libFileGDBAPI" >&2;}
 fi
+
+if test "$HAVE_TEIGHA" = "yes" -a "$ECW_54" = "yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Both Teigha SDK and ECW SDK >= 5.4 found. This was found to cause crashes in ECW driver." >&5
+$as_echo "$as_me: WARNING: Both Teigha SDK and ECW SDK >= 5.4 found. This was found to cause crashes in ECW driver." >&2;}
+fi
diff --git a/configure.ac b/configure.ac
index 5049906..345684f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 dnl ***************************************************************************
-dnl $Id: configure.ac 40330 2017-10-05 12:56:50Z rouault $
+dnl $Id: configure.ac 41784 2018-03-13 20:20:56Z rouault $
 dnl
 dnl Project:  GDAL
 dnl Purpose:  Configure source file.
@@ -2682,6 +2682,7 @@ dnl ---------------------------------------------------------------------------
 ECW_FLAGS=
 ECW_LIBS=
 ECW_INCLUDE=
+ECW_54=
 
 AC_ARG_WITH(ecw,[  --with-ecw[=ARG]        Include ECW support (ARG=ECW SDK Path, yes or no)],,)
 
@@ -2744,19 +2745,59 @@ else
 
   # ECW SDK 5.0 style and also for the case where license type is included in path i.e. specific license type is requested.
   elif test -r $with_ecw/lib/$ECW_ARCH/$ECW_CONF/libNCSEcw.a ; then
-    ECW_LIBDIR=$with_ecw/lib/$ECW_ARCH/$ECW_CONF
-    ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
-    AC_MSG_RESULT([found Intergraph 5.x+ SDK in ${ECW_LIBDIR}.])
+    # Test if we must use the newabi version (SDK 5.4)
+    if test -r $with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then
+        echo "#include <string>" > testnewabi.cpp
+        echo "namespace NCS { class CString { public: static std::wstring Utf8Decode (const std::string &sUtf8); }; }" >> testnewabi.cpp
+        echo "int main() { return static_cast<int>(NCS::CString::Utf8Decode(std::string()).size()); }" >> testnewabi.cpp
+        if test -z "`${CXX} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then
+            ECW_LIBDIR=$with_ecw/lib/newabi/$ECW_ARCH/$ECW_CONF
+            ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
+            with_ecw=$with_ecw/$ecw_license_type
+            ECW_54="yes"
+            AC_MSG_RESULT([found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}.])
+            rm -f testnewabi.*
+            rm -f testnewabi
+            break
+        fi
+        rm -f testnewabi.*
+        rm -f testnewabi
+    fi
+    if test "$ECW_LIBS" = ""; then
+        ECW_LIBDIR=$with_ecw/lib/$ECW_ARCH/$ECW_CONF
+        ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
+        AC_MSG_RESULT([found Intergraph 5.x+ SDK in ${ECW_LIBDIR}.])
+    fi
  # ECWJP2 SDK 5.1 style
   elif test -d $with_ecw; then
     for ecw_license_type in "Desktop_Read-Write" "Server_Read-Only_EndUser" "Server_Read-Only" "Server_Read-Write" "Desktop_Read-Only"
       do
-        ECW_LIBDIR=$with_ecw/$ecw_license_type/lib/$ECW_ARCH/$ECW_CONF
-        if test -r $ECW_LIBDIR/libNCSEcw.a; then
-          ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
-          with_ecw=$with_ecw/$ecw_license_type
-          AC_MSG_RESULT([found Intergraph 5.x+ SDK in ${ECW_LIBDIR}.])
-          break
+        # Test if we must use the newabi version (SDK 5.4)
+        if test -r $with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF/libNCSEcw.a; then
+            echo "#include <string>" > testnewabi.cpp
+            echo "namespace NCS { class CString { public: static std::wstring Utf8Decode (const std::string &sUtf8); }; }" >> testnewabi.cpp
+            echo "int main() { return static_cast<int>(NCS::CString::Utf8Decode(std::string()).size()); }" >> testnewabi.cpp
+            if test -z "`${CXX} ${CPPFLAGS} testnewabi.cpp -L$with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF -lNCSEcw -o testnewabi 2>&1`" ; then
+                ECW_LIBDIR=$with_ecw/$ecw_license_type/lib/newabi/$ECW_ARCH/$ECW_CONF
+                ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
+                with_ecw=$with_ecw/$ecw_license_type
+                AC_MSG_RESULT([found Intergraph 5.4+ SDK with newabi in ${ECW_LIBDIR}.])
+                ECW_54="yes"
+                rm -f testnewabi.*
+                rm -f testnewabi
+                break
+            fi
+            rm -f testnewabi.*
+            rm -f testnewabi
+        fi
+        if test "$ECW_LIBS" = ""; then
+            ECW_LIBDIR=$with_ecw/$ecw_license_type/lib/$ECW_ARCH/$ECW_CONF
+            if test -r $ECW_LIBDIR/libNCSEcw.a; then
+                ECW_LIBS="-L$ECW_LIBDIR -lNCSEcw $ECW_FRAMEWORK_COCOA"
+                with_ecw=$with_ecw/$ecw_license_type
+                AC_MSG_RESULT([found Intergraph 5.x+ SDK in ${ECW_LIBDIR}.])
+                break
+            fi
         fi
       done
  else
@@ -5576,3 +5617,7 @@ dnl FileGDB v1.5
 if test "$PROJ_STATIC" = "no" -a "$FGDB_ENABLED" = "yes" -a "$FGDB_HAS_PROJ4" = "yes"; then
     AC_MSG_WARN([--without-static-proj and --with-fgdb are both available. There might be some incompatibility between system libproj and the embedded copy within libFileGDBAPI])
 fi
+
+if test "$HAVE_TEIGHA" = "yes" -a "$ECW_54" = "yes"; then
+    AC_MSG_WARN([Both Teigha SDK and ECW SDK >= 5.4 found. This was found to cause crashes in ECW driver.])
+fi
diff --git a/frmts/airsar/airsardataset.cpp b/frmts/airsar/airsardataset.cpp
index 2c52ac3..c992a9d 100644
--- a/frmts/airsar/airsardataset.cpp
+++ b/frmts/airsar/airsardataset.cpp
@@ -33,7 +33,7 @@
 #include "gdal_frmts.h"
 #include "gdal_pam.h"
 
-CPL_CVSID("$Id: airsardataset.cpp 36501 2016-11-25 14:09:24Z rouault $");
+CPL_CVSID("$Id: airsardataset.cpp 41376 2018-02-01 17:02:05Z rouault $");
 
 /************************************************************************/
 /* ==================================================================== */
@@ -238,7 +238,7 @@ CPLErr AirSARRasterBand::IReadBlock( int /* nBlockXOff */,
             pafLine[iPixel*2 + 0] = (float)(SQRT_2 * (m[M13] - m[M23]));
 
             // imaginary
-            pafLine[iPixel*2 + 1] = (float)(SQRT_2 * (m[M23] - m[M14]));
+            pafLine[iPixel*2 + 1] = (float)(SQRT_2 * (m[M24] - m[M14]));
         }
     }
     else if( nBand == 6 ) /* C33 */
diff --git a/frmts/gtiff/geotiff.cpp b/frmts/gtiff/geotiff.cpp
index bd7ccd0..e0bf1f5 100644
--- a/frmts/gtiff/geotiff.cpp
+++ b/frmts/gtiff/geotiff.cpp
@@ -106,7 +106,7 @@
 #include "xtiffio.h"
 
 
-CPL_CVSID("$Id: geotiff.cpp 40691 2017-11-11 16:25:25Z rouault $");
+CPL_CVSID("$Id: geotiff.cpp 41666 2018-03-08 14:53:26Z rouault $");
 
 #if SIZEOF_VOIDP == 4
 static bool bGlobalStripIntegerOverflow = false;
@@ -9413,9 +9413,9 @@ static void CreateTIFFColorTable(GDALColorTable* poColorTable,
 
             poColorTable->GetColorEntryAsRGB( iColor, &sRGB );
 
-            anTRed[iColor] = static_cast<unsigned short>(256 * sRGB.c1);
-            anTGreen[iColor] = static_cast<unsigned short>(256 * sRGB.c2);
-            anTBlue[iColor] = static_cast<unsigned short>(256 * sRGB.c3);
+            anTRed[iColor] = static_cast<unsigned short>(257 * sRGB.c1);
+            anTGreen[iColor] = static_cast<unsigned short>(257 * sRGB.c2);
+            anTBlue[iColor] = static_cast<unsigned short>(257 * sRGB.c3);
         }
         else
         {
@@ -13168,7 +13168,7 @@ CPLErr GTiffDataset::OpenOffset( TIFF *hTIFFIn,
         for( int iColor = nColorCount - 1; iColor >= 0; iColor-- )
         {
             // TODO(schwehr): Ensure the color entries are never negative?
-            const unsigned short divisor = 256;
+            const unsigned short divisor = 257;
             const GDALColorEntry oEntry = {
                 static_cast<short>(panRed[iColor] / divisor),
                 static_cast<short>(panGreen[iColor] / divisor),
@@ -15521,7 +15521,7 @@ GDALDataset *GTiffDataset::Create( const char * pszFilename,
 
         for( int iColor = nColorCount - 1; iColor >= 0; iColor-- )
         {
-            const unsigned short divisor = 256;
+            const unsigned short divisor = 257;
             const GDALColorEntry oEntry = {
                 static_cast<short>(panRed[iColor] / divisor),
                 static_cast<short>(panGreen[iColor] / divisor),
@@ -16042,9 +16042,9 @@ GTiffDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS,
 
                 poCT->GetColorEntryAsRGB( iColor, &sRGB );
 
-                panTRed[iColor] = static_cast<unsigned short>(256 * sRGB.c1);
-                panTGreen[iColor] = static_cast<unsigned short>(256 * sRGB.c2);
-                panTBlue[iColor] = static_cast<unsigned short>(256 * sRGB.c3);
+                panTRed[iColor] = static_cast<unsigned short>(257 * sRGB.c1);
+                panTGreen[iColor] = static_cast<unsigned short>(257 * sRGB.c2);
+                panTBlue[iColor] = static_cast<unsigned short>(257 * sRGB.c3);
             }
             else
             {
diff --git a/frmts/netcdf/netcdfdataset.cpp b/frmts/netcdf/netcdfdataset.cpp
index a542af3..df442ae 100644
--- a/frmts/netcdf/netcdfdataset.cpp
+++ b/frmts/netcdf/netcdfdataset.cpp
@@ -62,7 +62,7 @@
 #include "ogr_core.h"
 #include "ogr_srs_api.h"
 
-CPL_CVSID("$Id: netcdfdataset.cpp 40424 2017-10-13 14:32:37Z rouault $");
+CPL_CVSID("$Id: netcdfdataset.cpp 40853 2017-11-27 10:19:18Z rouault $");
 
 // Internal function declarations.
 
@@ -150,7 +150,8 @@ class netCDFRasterBand : public GDALPamRasterBand
     bool        bSignedData;
     bool        bCheckLongitude;
 
-    CPLErr          CreateBandMetadata( const int *paDimIds );
+    CPLErr          CreateBandMetadata( const int *paDimIds,
+                                        const int* panExtraDimVarIds );
     template <class T> void CheckData ( void *pImage, void *pImageNC,
                                         size_t nTmpBlockXSize,
                                         size_t nTmpBlockYSize,
@@ -167,7 +168,8 @@ class netCDFRasterBand : public GDALPamRasterBand
                       const int *panBandZLen,
                       const int *panBandPos,
                       const int *paDimIds,
-                      int nBand );
+                      int nBand,
+                      const int *panExtraDimVarIds );
     netCDFRasterBand( netCDFDataset *poDS,
                       GDALDataType eType,
                       int nBand,
@@ -206,7 +208,8 @@ netCDFRasterBand::netCDFRasterBand( netCDFDataset *poNCDFDS,
                                     const int *panBandZLevIn,
                                     const int *panBandZPosIn,
                                     const int *paDimIds,
-                                    int nBandIn ) :
+                                    int nBandIn,
+                                    const int *panExtraDimVarIds ) :
     nc_datatype(NC_NAT),
     cdfid(poNCDFDS->GetCDFID()),
     nZId(nZIdIn),
@@ -468,7 +471,7 @@ netCDFRasterBand::netCDFRasterBand( netCDFDataset *poNCDFDS,
     SetNoDataValue(dfNoData);
 
     // Create Band Metadata.
-    CreateBandMetadata(paDimIds);
+    CreateBandMetadata(paDimIds, panExtraDimVarIds);
 
     // Attempt to fetch the scale_factor and add_offset attributes for the
     // variable and set them.  If these values are not available, set
@@ -1116,10 +1119,80 @@ CPLXMLNode *netCDFRasterBand::SerializeToXML( const char * /* pszUnused */ )
 }
 
 /************************************************************************/
+/*               Get1DVariableIndexedByDimension()                      */
+/************************************************************************/
+
+static int Get1DVariableIndexedByDimension( int cdfid, int nDimId,
+                                            const char* pszDimName,
+                                            bool bVerboseError )
+{
+    int nVarID;
+    // First try to find a variable whose name is identical to the dimension
+    // name, and check that it is indeed indexed by this dimension
+    if( nc_inq_varid(cdfid, pszDimName, &nVarID) == NC_NOERR )
+    {
+        int nDimCountOfVariable = 0;
+        nc_inq_varndims(cdfid, nVarID, &nDimCountOfVariable);
+        if( nDimCountOfVariable == 1 )
+        {
+            int nDimIdOfVariable = -1;
+            nc_inq_vardimid(cdfid, nVarID, &nDimIdOfVariable);
+            if( nDimIdOfVariable == nDimId )
+            {
+                return nVarID;
+            }
+        }
+    }
+
+    // Otherwise iterate over the variables to find potential candidates
+    int nvars = 0;
+    CPL_IGNORE_RET_VAL( nc_inq(cdfid, NULL, &nvars, NULL, NULL) );
+
+    int nCountCandidateVars = 0;
+    int nCandidateVarID = -1;
+    for( int k = 0; k < nvars; k++ )
+    {
+        int nDimCountOfVariable = 0;
+        nc_inq_varndims(cdfid, k, &nDimCountOfVariable);
+        if( nDimCountOfVariable == 1 )
+        {
+            int nDimIdOfVariable = -1;
+            nc_inq_vardimid(cdfid, k, &nDimIdOfVariable);
+            if( nDimIdOfVariable == nDimId )
+            {
+                nCountCandidateVars ++;
+                nCandidateVarID = k;
+            }
+        }
+    }
+    if( nCountCandidateVars > 1 )
+    {
+        if( bVerboseError )
+        {
+            CPLError(CE_Warning, CPLE_AppDefined,
+                 "Several 1D variables are indexed by dimension %s",
+                 pszDimName);
+        }
+        return -1;
+    }
+    else if( nCandidateVarID < 0 )
+    {
+        if( bVerboseError )
+        {
+            CPLError(CE_Warning, CPLE_AppDefined,
+                 "No 1D variable is indexed by dimension %s",
+                 pszDimName);
+        }
+    }
+    return nCandidateVarID;
+}
+
+/************************************************************************/
 /*                         CreateBandMetadata()                         */
 /************************************************************************/
 
-CPLErr netCDFRasterBand::CreateBandMetadata( const int *paDimIds )
+CPLErr netCDFRasterBand::CreateBandMetadata( const int *paDimIds,
+                                             const int* panExtraDimVarIds )
 
 {
     netCDFDataset *l_poDS = reinterpret_cast<netCDFDataset *>(poDS);
@@ -1148,7 +1221,6 @@ CPLErr netCDFRasterBand::CreateBandMetadata( const int *paDimIds )
     }
 
     // Loop over non-spatial dimensions.
-    int nVarID = -1;
     int result = 0;
     int Taken = 0;
 
@@ -1171,131 +1243,131 @@ CPLErr netCDFRasterBand::CreateBandMetadata( const int *paDimIds )
         snprintf(szVarName, sizeof(szVarName), "%s",
                  l_poDS->papszDimName[paDimIds[panBandZPos[i]]]);
 
-        // TODO: Make sure all the status checks make sense.
+        char szMetaName[NC_MAX_NAME + 1 + 32];
+        snprintf(szMetaName, sizeof(szMetaName), "NETCDF_DIM_%s", szVarName);
 
-        status = nc_inq_varid(cdfid, szVarName, &nVarID);
-        if( status != NC_NOERR )
+        int nVarID = panExtraDimVarIds[i];
+        if( nVarID < 0 )
         {
-            // Try to uppercase the first letter of the variable.
-            // Note: Why is this needed?  Leaving for safety.
-            szVarName[0] = static_cast<char>(toupper(szVarName[0]));
-            /* status = */ nc_inq_varid(cdfid, szVarName, &nVarID);
+            SetMetadataItem(szMetaName, CPLSPrintf("%d", result + 1));
         }
+        else
+        {
+            // TODO: Make sure all the status checks make sense.
 
-        nc_type nVarType = NC_NAT;
-        /* status = */ nc_inq_vartype(cdfid, nVarID, &nVarType);
-
-        int nDims = 0;
-        /* status = */ nc_inq_varndims(cdfid, nVarID, &nDims);
+            nc_type nVarType = NC_NAT;
+            /* status = */ nc_inq_vartype(cdfid, nVarID, &nVarType);
 
-        char szMetaTemp[256] = {};
-        if( nDims == 1 )
-        {
-            size_t count[1] = { 1 };
-            size_t start[1] = { static_cast<size_t>(result) };
+            int nDims = 0;
+            /* status = */ nc_inq_varndims(cdfid, nVarID, &nDims);
 
-            switch( nVarType )
+            char szMetaTemp[256] = {};
+            if( nDims == 1 )
             {
-                case NC_BYTE:
-                    // TODO: Check for signed/unsigned byte.
-                    signed char cData;
-                    /* status = */ nc_get_vara_schar(cdfid, nVarID,
-                                                 start,
-                                                 count, &cData);
-                    snprintf(szMetaTemp, sizeof(szMetaTemp), "%d", cData);
-                    break;
-                case NC_SHORT:
-                    short sData;
-                    /* status = */ nc_get_vara_short(cdfid, nVarID,
-                                                 start,
-                                                 count, &sData);
-                    snprintf(szMetaTemp, sizeof(szMetaTemp), "%d", sData);
-                    break;
-                case NC_INT:
-                {
-                    int nData;
-                    /* status = */ nc_get_vara_int(cdfid, nVarID,
-                                               start,
-                                               count, &nData);
-                    snprintf(szMetaTemp, sizeof(szMetaTemp), "%d", nData);
-                    break;
-                }
-                case NC_FLOAT:
-                    float fData;
-                    /* status = */ nc_get_vara_float(cdfid, nVarID,
-                                                 start,
-                                                 count, &fData);
-                    CPLsnprintf(szMetaTemp, sizeof(szMetaTemp),
-                                 "%.8g", fData);
-                    break;
-                case NC_DOUBLE:
-                    double dfData;
-                    /* status = */ nc_get_vara_double(cdfid, nVarID,
-                                                  start,
-                                                  count, &dfData);
-                    CPLsnprintf(szMetaTemp, sizeof(szMetaTemp),
-                                 "%.16g", dfData);
-                    break;
-#ifdef NETCDF_HAS_NC4
-                case NC_UBYTE:
-                    unsigned char ucData;
-                    /* status = */ nc_get_vara_uchar(cdfid, nVarID,
-                                                 start,
-                                                 count, &ucData);
-                    snprintf(szMetaTemp, sizeof(szMetaTemp), "%u", ucData);
-                    break;
-                case NC_USHORT:
-                    unsigned short usData;
-                    /* status = */ nc_get_vara_ushort(cdfid, nVarID,
-                                                  start,
-                                                  count, &usData);
-                    snprintf(szMetaTemp, sizeof(szMetaTemp), "%u", usData);
-                    break;
-                case NC_UINT:
-                {
-                    unsigned int unData;
-                    /* status = */ nc_get_vara_uint(cdfid, nVarID,
-                                                start,
-                                                count, &unData);
-                    snprintf(szMetaTemp, sizeof(szMetaTemp), "%u", unData);
-                    break;
-                }
-                case NC_INT64:
+                size_t count[1] = { 1 };
+                size_t start[1] = { static_cast<size_t>(result) };
+
+                switch( nVarType )
                 {
-                    long long nData;
-                    /* status = */ nc_get_vara_longlong(cdfid, nVarID,
+                    case NC_BYTE:
+                        // TODO: Check for signed/unsigned byte.
+                        signed char cData;
+                        /* status = */ nc_get_vara_schar(cdfid, nVarID,
+                                                    start,
+                                                    count, &cData);
+                        snprintf(szMetaTemp, sizeof(szMetaTemp), "%d", cData);
+                        break;
+                    case NC_SHORT:
+                        short sData;
+                        /* status = */ nc_get_vara_short(cdfid, nVarID,
+                                                    start,
+                                                    count, &sData);
+                        snprintf(szMetaTemp, sizeof(szMetaTemp), "%d", sData);
+                        break;
+                    case NC_INT:
+                    {
+                        int nData;
+                        /* status = */ nc_get_vara_int(cdfid, nVarID,
                                                 start,
                                                 count, &nData);
-                    snprintf(szMetaTemp, sizeof(szMetaTemp), CPL_FRMT_GIB, nData);
-                    break;
-                }
-                case NC_UINT64:
-                {
-                    unsigned long long unData;
-                    /* status = */ nc_get_vara_ulonglong(cdfid, nVarID,
-                                                start,
-                                                count, &unData);
-                    snprintf(szMetaTemp, sizeof(szMetaTemp), CPL_FRMT_GUIB, unData);
-                    break;
+                        snprintf(szMetaTemp, sizeof(szMetaTemp), "%d", nData);
+                        break;
+                    }
+                    case NC_FLOAT:
+                        float fData;
+                        /* status = */ nc_get_vara_float(cdfid, nVarID,
+                                                    start,
+                                                    count, &fData);
+                        CPLsnprintf(szMetaTemp, sizeof(szMetaTemp),
+                                    "%.8g", fData);
+                        break;
+                    case NC_DOUBLE:
+                        double dfData;
+                        /* status = */ nc_get_vara_double(cdfid, nVarID,
+                                                    start,
+                                                    count, &dfData);
+                        CPLsnprintf(szMetaTemp, sizeof(szMetaTemp),
+                                    "%.16g", dfData);
+                        break;
+    #ifdef NETCDF_HAS_NC4
+                    case NC_UBYTE:
+                        unsigned char ucData;
+                        /* status = */ nc_get_vara_uchar(cdfid, nVarID,
+                                                    start,
+                                                    count, &ucData);
+                        snprintf(szMetaTemp, sizeof(szMetaTemp), "%u", ucData);
+                        break;
+                    case NC_USHORT:
+                        unsigned short usData;
+                        /* status = */ nc_get_vara_ushort(cdfid, nVarID,
+                                                    start,
+                                                    count, &usData);
+                        snprintf(szMetaTemp, sizeof(szMetaTemp), "%u", usData);
+                        break;
+                    case NC_UINT:
+                    {
+                        unsigned int unData;
+                        /* status = */ nc_get_vara_uint(cdfid, nVarID,
+                                                    start,
+                                                    count, &unData);
+                        snprintf(szMetaTemp, sizeof(szMetaTemp), "%u", unData);
+                        break;
+                    }
+                    case NC_INT64:
+                    {
+                        long long nData;
+                        /* status = */ nc_get_vara_longlong(cdfid, nVarID,
+                                                    start,
+                                                    count, &nData);
+                        snprintf(szMetaTemp, sizeof(szMetaTemp), CPL_FRMT_GIB, nData);
+                        break;
+                    }
+                    case NC_UINT64:
+                    {
+                        unsigned long long unData;
+                        /* status = */ nc_get_vara_ulonglong(cdfid, nVarID,
+                                                    start,
+                                                    count, &unData);
+                        snprintf(szMetaTemp, sizeof(szMetaTemp), CPL_FRMT_GUIB, unData);
+                        break;
+                    }
+    #endif
+                    default:
+                        CPLDebug("GDAL_netCDF", "invalid dim %s, type=%d",
+                                szMetaTemp, nVarType);
+                        break;
                 }
-#endif
-                default:
-                    CPLDebug("GDAL_netCDF", "invalid dim %s, type=%d",
-                             szMetaTemp, nVarType);
-                    break;
             }
-        }
-        else
-        {
-            snprintf(szMetaTemp, sizeof(szMetaTemp), "%d", result + 1);
-        }
+            else
+            {
+                snprintf(szMetaTemp, sizeof(szMetaTemp), "%d", result + 1);
+            }
 
-        // Save dimension value.
-        // NOTE: removed #original_units as not part of CF-1.
+            // Save dimension value.
+            // NOTE: removed #original_units as not part of CF-1.
 
-        char szMetaName[NC_MAX_NAME + 1 + 32];
-        snprintf(szMetaName, sizeof(szMetaName), "NETCDF_DIM_%s", szVarName);
-        SetMetadataItem(szMetaName, szMetaTemp);
+            SetMetadataItem(szMetaName, szMetaTemp);
+        }
 
         Taken += result * Sum;
     }  // End loop non-spatial dimensions.
@@ -6655,6 +6727,7 @@ GDALDataset *netCDFDataset::Open( GDALOpenInfo *poOpenInfo )
     nc_type nType = NC_NAT;
 
     CPLString osExtraDimNames;
+    int anExtraDimVarIds[NC_MAX_NAME] = { -1 };
 
     if( nd > 2 )
     {
@@ -6673,7 +6746,7 @@ GDALDataset *netCDFDataset::Open( GDALOpenInfo *poOpenInfo )
                 nc_inq_dimlen(cdfid, paDimIds[j], &lev_count);
                 nTotLevCount *= lev_count;
                 panBandZLev[nDim - 2] = static_cast<int>(lev_count);
-                panBandDimPos[nDim++] = j;  // Save Position of ZDim
+                panBandDimPos[nDim] = j;  // Save Position of ZDim
                 // Save non-spatial dimension names.
                 if( nc_inq_dimname(cdfid, paDimIds[j], szDimName)
                     == NC_NOERR )
@@ -6683,25 +6756,40 @@ GDALDataset *netCDFDataset::Open( GDALOpenInfo *poOpenInfo )
                     {
                         osExtraDimNames += ",";
                     }
-                    nc_inq_varid(cdfid, szDimName, &nVarID);
-                    nc_inq_vartype(cdfid, nVarID, &nType);
-                    char szExtraDimDef[NC_MAX_NAME + 1];
-                    snprintf(szExtraDimDef, sizeof(szExtraDimDef), "{%ld,%d}",
-                             (long)lev_count, nType);
-                    char szTemp[NC_MAX_NAME + 32 + 1];
-                    snprintf(szTemp, sizeof(szTemp), "NETCDF_DIM_%s_DEF",
-                             szDimName);
-                    poDS->papszMetadata = CSLSetNameValue(
-                        poDS->papszMetadata, szTemp, szExtraDimDef);
-                    if( NCDFGet1DVar(cdfid, nVarID, &pszTemp) == CE_None )
+
+                    int nIdxVarID = Get1DVariableIndexedByDimension(cdfid,
+                                                            paDimIds[j],
+                                                            szDimName,
+                                                            true);
+                    anExtraDimVarIds[nDim-2] = nIdxVarID;
+
+                    if( nIdxVarID >= 0 )
                     {
-                        snprintf(szTemp, sizeof(szTemp), "NETCDF_DIM_%s_VALUES",
-                                 szDimName);
+                        nc_inq_vartype(cdfid, nIdxVarID, &nType);
+                        char szExtraDimDef[NC_MAX_NAME + 1];
+                        snprintf(szExtraDimDef, sizeof(szExtraDimDef), "{%ld,%d}",
+                                (long)lev_count, nType);
+                        char szTemp[NC_MAX_NAME + 32 + 1];
+                        snprintf(szTemp, sizeof(szTemp), "NETCDF_DIM_%s_DEF",
+                                szDimName);
                         poDS->papszMetadata = CSLSetNameValue(
-                            poDS->papszMetadata, szTemp, pszTemp);
-                        CPLFree(pszTemp);
+                            poDS->papszMetadata, szTemp, szExtraDimDef);
+                        if( NCDFGet1DVar(cdfid, nIdxVarID, &pszTemp) == CE_None )
+                        {
+                            snprintf(szTemp, sizeof(szTemp), "NETCDF_DIM_%s_VALUES",
+                                    szDimName);
+                            poDS->papszMetadata = CSLSetNameValue(
+                                poDS->papszMetadata, szTemp, pszTemp);
+                            CPLFree(pszTemp);
+                        }
                     }
                 }
+                else
+                {
+                    anExtraDimVarIds[nDim-2] = -1;
+                }
+
+                nDim ++;
             }
         }
         osExtraDimNames += "}";
@@ -6731,7 +6819,8 @@ GDALDataset *netCDFDataset::Open( GDALOpenInfo *poOpenInfo )
     {
         netCDFRasterBand *poBand =
             new netCDFRasterBand(poDS, var, nDim, lev, panBandZLev,
-                                 panBandDimPos, paDimIds, lev + 1);
+                                 panBandDimPos, paDimIds, lev + 1,
+                                 anExtraDimVarIds);
         poDS->SetBand(lev + 1, poBand);
     }
 
diff --git a/frmts/nitf/nitfimage.c b/frmts/nitf/nitfimage.c
index 0b756bd..b30ad28 100644
--- a/frmts/nitf/nitfimage.c
+++ b/frmts/nitf/nitfimage.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: nitfimage.c 36380 2016-11-21 10:21:20Z rouault $
+ * $Id: nitfimage.c 41147 2017-12-30 09:06:46Z rouault $
  *
  * Project:  NITF Read/Write Library
  * Purpose:  Module responsible for implementation of most NITFImage
@@ -36,7 +36,7 @@
 #include "cpl_conv.h"
 #include "cpl_string.h"
 
-CPL_CVSID("$Id: nitfimage.c 36380 2016-11-21 10:21:20Z rouault $");
+CPL_CVSID("$Id: nitfimage.c 41147 2017-12-30 09:06:46Z rouault $");
 
 CPL_INLINE static void CPL_IGNORE_RET_VAL_INT(CPL_UNUSED int unused) {}
 
@@ -4290,11 +4290,11 @@ int NITFReadIMRFCA( NITFImage *psImage, NITFRPC00BInfo *psRPC )
 
     for( count = 0; count < 20; ++count )
     {
-        psRPC->LINE_NUM_COEFF[count] = CPLAtof( NITFGetField(szTemp, pachTreIMRFCA, count*22,     22) );
-        psRPC->LINE_DEN_COEFF[count] = CPLAtof( NITFGetField(szTemp, pachTreIMRFCA, 440+count*22, 22) );
+        psRPC->SAMP_NUM_COEFF[count] = CPLAtof( NITFGetField(szTemp, pachTreIMRFCA, count*22,     22) );
+        psRPC->SAMP_DEN_COEFF[count] = CPLAtof( NITFGetField(szTemp, pachTreIMRFCA, 440+count*22, 22) );
 
-        psRPC->SAMP_NUM_COEFF[count] = CPLAtof( NITFGetField(szTemp, pachTreIMRFCA, 880+count*22,  22) );
-        psRPC->SAMP_DEN_COEFF[count] = CPLAtof( NITFGetField(szTemp, pachTreIMRFCA, 1320+count*22, 22) );
+        psRPC->LINE_NUM_COEFF[count] = CPLAtof( NITFGetField(szTemp, pachTreIMRFCA, 880+count*22,  22) );
+        psRPC->LINE_DEN_COEFF[count] = CPLAtof( NITFGetField(szTemp, pachTreIMRFCA, 1320+count*22, 22) );
     }
 
     psRPC->SUCCESS = 1;
diff --git a/frmts/pcraster/GNUmakefile b/frmts/pcraster/GNUmakefile
index 9f8079f..b252cc6 100644
--- a/frmts/pcraster/GNUmakefile
+++ b/frmts/pcraster/GNUmakefile
@@ -5,7 +5,7 @@ CPPFLAGS := $(XTRA_OPT)  $(CPPFLAGS)
 
 ifeq ($(PCRASTER_SETTING),internal)
 CPPFLAGS += -DUSE_IN_GDAL -Ilibcsf
-OBJ = _getcell.o _getrow.o _gsomece.o _putcell.o _rputrow.o angle.o attravai.o attrsize.o cellsize.o create2.o csfglob.o csfsup.o delattr.o dumconv.o endian.o filename.o gattrblk.o gattridx.o gcellrep.o gdattype.o getattr.o getx0.o gety0.o ggisfid.o gmaxval.o gminval.o gnrcols.o gnrrows.o gproj.o gputproj.o gvalscal.o gvartype.o gversion.o ismv.o kernlcsf.o legend.o mclose.o mopen.o moreattr.o mperror.o pgisfid.o pmaxval.o pminval.o putallmv.o putattr.o putsomec.o putx0.o puty0.o pvalsca [...]
+OBJ = _getcell.o _getrow.o _gsomece.o _putcell.o _rputrow.o angle.o attravai.o attrsize.o cellsize.o create2.o csfglob.o csfsup.o delattr.o dumconv.o endian.o file.o filename.o gattrblk.o gattridx.o gcellrep.o gdattype.o getattr.o getx0.o gety0.o ggisfid.o gmaxval.o gminval.o gnrcols.o gnrrows.o gproj.o gputproj.o gvalscal.o gvartype.o gversion.o ismv.o kernlcsf.o legend.o mclose.o mopen.o moreattr.o mperror.o pgisfid.o pmaxval.o pminval.o putallmv.o putattr.o putsomec.o putx0.o puty0.o  [...]
 endif
 
 OBJ += pcrasterdataset.o pcrastermisc.o pcrasterrasterband.o pcrasterutil.o
diff --git a/frmts/pcraster/libcsf/README b/frmts/pcraster/libcsf/README
index a6ba323..679dc3b 100644
--- a/frmts/pcraster/libcsf/README
+++ b/frmts/pcraster/libcsf/README
@@ -2,10 +2,9 @@ This library reads and writes the native PCRaster format, formerly known as CSF.
 
 More information about PCRaster can be found at:
 http://www.pcraster.eu
-http://pcraster.geo.uu.nl
 
 Questions can be directed to the PCRaster mailing list:
 http://pcraster.geo.uu.nl/support/questions-2/
 
-Bug reports can be submitted to the PCRaster SourceForge page:
-http://sourceforge.net/p/pcraster/bugs-and-feature-requests/milestone/PCRaster/
+Bug reports can be submitted to the Github page:
+https://github.com/pcraster/rasterformat/issues
diff --git a/frmts/pcraster/libcsf/_gsomece.c b/frmts/pcraster/libcsf/_gsomece.c
index 84e293a..4b1cee2 100644
--- a/frmts/pcraster/libcsf/_gsomece.c
+++ b/frmts/pcraster/libcsf/_gsomece.c
@@ -27,7 +27,7 @@ size_t RgetSomeCells(
 
 	offset <<= LOG_CELLSIZE(inFileCR);
 	readAt = ADDR_DATA + (CSF_FADDR)offset;
-	if( fseek(map->fp, (long)readAt, SEEK_SET) != 0 )
+	if(csf_fseek(map->fp, readAt, SEEK_SET) != 0 )
             return 0;
 	cellsRead = map->read(buf, (size_t)CELLSIZE(inFileCR),
 	(size_t)nrCells, map->fp);
diff --git a/frmts/pcraster/libcsf/attrsize.c b/frmts/pcraster/libcsf/attrsize.c
index b8363f9..9d1f511 100644
--- a/frmts/pcraster/libcsf/attrsize.c
+++ b/frmts/pcraster/libcsf/attrsize.c
@@ -1,5 +1,6 @@
 #include "csf.h"
 #include "csfimpl.h"
+#include <string.h>
 
 /* get the size of an attribute (LIBRARY_INTERNAL)
  * returns
diff --git a/frmts/pcraster/libcsf/create2.c b/frmts/pcraster/libcsf/create2.c
index abc47bd..287ba09 100644
--- a/frmts/pcraster/libcsf/create2.c
+++ b/frmts/pcraster/libcsf/create2.c
@@ -193,14 +193,14 @@ MAP *Rcreate(
 	/* enlarge the file to the length needed by seeking and writing
 	one byte of crap */
 
-	if ( fseek(newMap->fp, (long)(fileSize-1),SEEK_SET) || /* fsetpos() is better */
+	if ( csf_fseek(newMap->fp, fileSize-1, SEEK_SET) || /* fsetpos() is better */
 	    newMap->write(&crap, (size_t)1, (size_t)1, newMap->fp) != 1 )
 	{
 		M_ERROR(NOSPACE);
 		goto error_open;
 	}
 	(void)fflush(newMap->fp);
-	if ( ftell(newMap->fp) != (long)fileSize)
+	if ( csf_ftell(newMap->fp) != (CSF_FADDR)fileSize)
 	{
 		M_ERROR(NOSPACE);
 		goto error_open;
diff --git a/frmts/pcraster/libcsf/csf.h b/frmts/pcraster/libcsf/csf.h
index c9cb3fe..3298702 100644
--- a/frmts/pcraster/libcsf/csf.h
+++ b/frmts/pcraster/libcsf/csf.h
@@ -40,7 +40,12 @@ typedef REAL8 CSF_VAR_TYPE;
  * (0) of the file                                
  */
 typedef UINT4 CSF_FADDR32;
-typedef long  CSF_FADDR;
+#if defined(_WIN32) && !defined(__MINGW32__)
+  /* long is 32 bit on Windows */
+  typedef __int64 CSF_FADDR;
+#else
+  typedef long    CSF_FADDR;
+#endif
 
 /* value for first 27 bytes of MAIN_HEADER.signature */
 #define CSF_SIG  "RUU CROSS SYSTEM MAP FORMAT"
diff --git a/frmts/pcraster/libcsf/csfimpl.h b/frmts/pcraster/libcsf/csfimpl.h
index 61d91ef..d115a30 100644
--- a/frmts/pcraster/libcsf/csfimpl.h
+++ b/frmts/pcraster/libcsf/csfimpl.h
@@ -235,4 +235,11 @@ int CsfValidSize(size_t size);
 				M_ERROR(ILLHANDLE);	\
 			}
 
+
+int                csf_fseek           (FILE* file,
+                                        CSF_FADDR offset,
+                                        int origin);
+
+CSF_FADDR          csf_ftell           (FILE* file);
+
 #endif /* CSF__IMPL_H */
diff --git a/frmts/pcraster/libcsf/file.c b/frmts/pcraster/libcsf/file.c
new file mode 100644
index 0000000..7423005
--- /dev/null
+++ b/frmts/pcraster/libcsf/file.c
@@ -0,0 +1,26 @@
+#include "csf.h"
+#include "csfimpl.h"
+
+
+int csf_fseek(
+    FILE* file,
+    CSF_FADDR offset,
+    int origin)
+{
+#if defined(_WIN32) && !defined(__MINGW32__)
+    return _fseeki64(file, offset, origin);
+#else
+    return fseek(file, offset, origin);
+#endif
+}
+
+
+CSF_FADDR csf_ftell(
+    FILE* file)
+{
+#if defined(_WIN32) && !defined(__MINGW32__)
+    return _ftelli64(file);
+#else
+    return ftell(file);
+#endif
+}
diff --git a/frmts/pcraster/libcsf/getattr.c b/frmts/pcraster/libcsf/getattr.c
index f809573..ec4fede 100644
--- a/frmts/pcraster/libcsf/getattr.c
+++ b/frmts/pcraster/libcsf/getattr.c
@@ -37,7 +37,7 @@ CSF_ATTR_ID CsfGetAttribute(
 		*nmemb /= elSize;
 		POSTCOND( (*nmemb) > 0);
 		pos =	b.attrs[i].attrOffset;
-		(void)fseek(m->fp, (long)pos, SEEK_SET); 
+		(void)csf_fseek(m->fp, pos, SEEK_SET); 
 		m->read(attr,elSize, (size_t)(*nmemb),m->fp);
 		return(id);
 	}
diff --git a/frmts/pcraster/libcsf/legend.c b/frmts/pcraster/libcsf/legend.c
index b95a6b6..e997fcf 100644
--- a/frmts/pcraster/libcsf/legend.c
+++ b/frmts/pcraster/libcsf/legend.c
@@ -66,7 +66,7 @@ int MgetLegend(
 	size_t i,nr,start = 0;
         if (pos == 0)
         	return 0;
-        if( fseek(m->fp, (long)pos, SEEK_SET) != 0 )
+        if( csf_fseek(m->fp, pos, SEEK_SET) != 0 )
                 return 0;
         if (id == ATTR_ID_LEGEND_V1)
         { 
diff --git a/frmts/pcraster/libcsf/makefile.vc b/frmts/pcraster/libcsf/makefile.vc
index 0656d55..14958c5 100644
--- a/frmts/pcraster/libcsf/makefile.vc
+++ b/frmts/pcraster/libcsf/makefile.vc
@@ -7,7 +7,7 @@ OBJ	=	endian.obj swapio.obj vs2.obj vsdef.obj rextend.obj\
 vsvers.obj legend.obj strpad.obj strconst.obj vsis.obj ruseas.obj rmalloc.obj create2.obj \
 _getcell.obj _getrow.obj _gsomece.obj _putcell.obj _rputrow.obj\
 attravai.obj attrsize.obj csfglob.obj csfsup.obj delattr.obj\
-filename.obj gattrblk.obj gattridx.obj gcellrep.obj \
+file.obj filename.obj gattrblk.obj gattridx.obj gcellrep.obj \
  cellsize.obj gdattype.obj getattr.obj getx0.obj\
 gety0.obj ggisfid.obj gmaxval.obj gminval.obj gnrcols.obj gnrrows.obj\
 gproj.obj gputproj.obj gvalscal.obj gvartype.obj gversion.obj ismv.obj\
diff --git a/frmts/pcraster/libcsf/mclose.c b/frmts/pcraster/libcsf/mclose.c
index 228e18b..79b6820 100644
--- a/frmts/pcraster/libcsf/mclose.c
+++ b/frmts/pcraster/libcsf/mclose.c
@@ -37,7 +37,7 @@ int Mclose(
      CsfSwap((void*)&(m->raster.maxVal), CELLSIZE(m->raster.cellRepr),(size_t)1);
     }
 
-    if(fseek(m->fp,(long)ADDR_MAIN_HEADER,SEEK_SET) != 0 ||
+    if(csf_fseek(m->fp, ADDR_MAIN_HEADER,SEEK_SET) != 0 ||
        m->write((void*)&(m->main.signature),sizeof(char), CSF_SIG_SPACE,m->fp)
                                                        != CSF_SIG_SPACE ||
        m->write((void*)&(m->main.version),sizeof(UINT2),(size_t)1,m->fp)!=1 ||
@@ -54,7 +54,7 @@ int Mclose(
     }
     
 
-    if ( fseek(m->fp,ADDR_SECOND_HEADER, SEEK_SET) != 0 ||
+    if ( csf_fseek(m->fp,ADDR_SECOND_HEADER, SEEK_SET) != 0 ||
         m->write((void*)&(m->raster.valueScale),sizeof(UINT2),(size_t)1,m->fp) !=1 ||
       m->write((void*)&(m->raster.cellRepr), sizeof(UINT2),(size_t)1,m->fp) !=1 ||
         fwrite((void*)&(m->raster.minVal), sizeof(CSF_VAR_TYPE),(size_t)1,m->fp) !=1 ||
diff --git a/frmts/pcraster/libcsf/mopen.c b/frmts/pcraster/libcsf/mopen.c
index 7995b09..fd58d58 100644
--- a/frmts/pcraster/libcsf/mopen.c
+++ b/frmts/pcraster/libcsf/mopen.c
@@ -85,14 +85,14 @@ MAP  *Mopen(
   *  fail
   */
 
- (void)fseek(m->fp,0L, SEEK_END);
- if (ftell(m->fp) < (long)ADDR_DATA)
+ (void)csf_fseek(m->fp,0, SEEK_END);
+ if (csf_ftell(m->fp) < ADDR_DATA)
  {
  	M_ERROR(NOT_CSF);
  	goto error_open;
  }
 
- (void)fseek(m->fp, 14+CSF_SIG_SPACE, SEEK_SET);
+ (void)csf_fseek(m->fp, 14+CSF_SIG_SPACE, SEEK_SET);
  if (1 != fread((void *)&s, sizeof(UINT4),(size_t)1,m->fp))
  {
      fprintf(stderr, "WARNING: Unable to read ORD_OK in CSF.\n");
@@ -116,7 +116,7 @@ MAP  *Mopen(
 #endif
  }
  
- (void)fseek(m->fp, ADDR_MAIN_HEADER, SEEK_SET);
+ (void)csf_fseek(m->fp, ADDR_MAIN_HEADER, SEEK_SET);
  m->read((void *)&(m->main.signature), sizeof(char), CSF_SIG_SPACE,m->fp);
  m->read((void *)&(m->main.version),   sizeof(UINT2),(size_t)1,m->fp);
  m->read((void *)&(m->main.gisFileId), sizeof(UINT4),(size_t)1,m->fp);
@@ -127,7 +127,7 @@ MAP  *Mopen(
  /*                                             14+CSF_SIG_SPACE
   */
  
- (void)fseek(m->fp, ADDR_SECOND_HEADER, SEEK_SET);
+ (void)csf_fseek(m->fp, ADDR_SECOND_HEADER, SEEK_SET);
  m->read((void *)&(m->raster.valueScale), sizeof(UINT2),(size_t)1,m->fp);
  m->read((void *)&(m->raster.cellRepr), sizeof(UINT2),(size_t)1,m->fp);
 
diff --git a/frmts/pcraster/libcsf/putattr.c b/frmts/pcraster/libcsf/putattr.c
index 610cb9d..01885c8 100644
--- a/frmts/pcraster/libcsf/putattr.c
+++ b/frmts/pcraster/libcsf/putattr.c
@@ -1,5 +1,7 @@
 #include "csf.h"
 #include "csfimpl.h"
+#include <assert.h>
+#include <string.h>
 
 /* make block empty
  */
@@ -177,10 +179,16 @@ CSF_FADDR32 CsfSeekAttrSpace(
 					noPosFound = 0;
                                         break;
 				case ATTR_NOT_USED:
-					if (i+1 == NR_ATTR_IN_BLOCK)
+					/*
+						KDJ: Commented out because control flow will never
+						reach it. See while condition above.
+						Added assert to document/verify this.
+					if (i == NR_ATTR_IN_BLOCK)
 						endBlock = b.next;
 					else
-						endBlock = b.attrs[i+1].attrOffset;
+					*/
+					assert(i < NR_ATTR_IN_BLOCK);
+					endBlock = b.attrs[i+1].attrOffset;
 					if ( (size_t)( endBlock - b.attrs[i].attrOffset) >= size)
 						/* this position can
 							hold the attr */
@@ -210,7 +218,7 @@ CSF_FADDR32 CsfSeekAttrSpace(
 		M_ERROR(WRITE_ERROR);
 		resultPos = 0;
 	}
-	if( fseek(m->fp, (long)resultPos, SEEK_SET) != 0 ) /* fsetpos() is better */
+	if( csf_fseek(m->fp, resultPos, SEEK_SET) != 0 ) /* fsetpos() is better */
         {
                 M_ERROR(WRITE_ERROR);
                 resultPos = 0;
diff --git a/frmts/pcraster/libcsf/putsomec.c b/frmts/pcraster/libcsf/putsomec.c
index ee44673..f99a4d7 100644
--- a/frmts/pcraster/libcsf/putsomec.c
+++ b/frmts/pcraster/libcsf/putsomec.c
@@ -257,7 +257,7 @@ size_t RputSomeCells(
 
 	writeAt  = ((CSF_FADDR)offset) << LOG_CELLSIZE(cr);
 	writeAt += ADDR_DATA;
-	if( fseek(map->fp, (long)writeAt, SEEK_SET) != 0 )
+	if( csf_fseek(map->fp, writeAt, SEEK_SET) != 0 )
             return 0;
 	return(map->write(buf, (size_t)CELLSIZE(cr), (size_t)nrCells, map->fp));
 }
diff --git a/frmts/pcraster/libcsf/rattrblk.c b/frmts/pcraster/libcsf/rattrblk.c
index 32db1bd..faec276 100644
--- a/frmts/pcraster/libcsf/rattrblk.c
+++ b/frmts/pcraster/libcsf/rattrblk.c
@@ -9,7 +9,7 @@ void CsfReadAttrBlock(
 	ATTR_CNTRL_BLOCK *b) /* write-only. attribute control block read */
 {
 	int i;
-	if (fseek(m->fp, (long)pos, SEEK_SET) != 0 )
+	if (csf_fseek(m->fp, pos, SEEK_SET) != 0 )
             return;
 	for(i=0; i < NR_ATTR_IN_BLOCK; i++)
 	{
diff --git a/frmts/pcraster/libcsf/ruseas.c b/frmts/pcraster/libcsf/ruseas.c
index 9670d9f..e017f7b 100644
--- a/frmts/pcraster/libcsf/ruseas.c
+++ b/frmts/pcraster/libcsf/ruseas.c
@@ -1,5 +1,6 @@
 #include "csf.h"
 #include "csfimpl.h"
+#include <string.h>
 
 static void UINT1tLdd(size_t nrCells, void *Buf)
 {
diff --git a/frmts/pcraster/libcsf/wattrblk.c b/frmts/pcraster/libcsf/wattrblk.c
index 53b58f2..b57f1a2 100644
--- a/frmts/pcraster/libcsf/wattrblk.c
+++ b/frmts/pcraster/libcsf/wattrblk.c
@@ -12,7 +12,7 @@ int CsfWriteAttrBlock(
 {
  int i;
 
- if ( fseek(m->fp,(long) pos, SEEK_SET) )
+ if ( csf_fseek(m->fp, pos, SEEK_SET) )
  	return 1;
 
  for(i=0; i < NR_ATTR_IN_BLOCK; i++)
diff --git a/frmts/raw/ehdrdataset.cpp b/frmts/raw/ehdrdataset.cpp
index d69afc4..edc155c 100644
--- a/frmts/raw/ehdrdataset.cpp
+++ b/frmts/raw/ehdrdataset.cpp
@@ -57,7 +57,7 @@
 #include "ogr_core.h"
 #include "ogr_spatialref.h"
 
-CPL_CVSID("$Id: ehdrdataset.cpp 37531 2017-03-01 04:56:18Z goatbar $");
+CPL_CVSID("$Id: ehdrdataset.cpp 41628 2018-03-04 11:38:29Z rouault $");
 
 static const int HAS_MIN_FLAG = 0x1;
 static const int HAS_MAX_FLAG = 0x2;
@@ -167,16 +167,18 @@ CPLErr EHdrRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
         return RawRasterBand::IReadBlock(nBlockXOff, nBlockYOff, pImage);
 
     // Establish desired position.
-    const vsi_l_offset nLineBytesBig =
-        (static_cast<vsi_l_offset>(nPixelOffsetBits) * nBlockXSize + 7) / 8;
-    if( nLineBytesBig >
-        static_cast<vsi_l_offset>(std::numeric_limits<int>::max()) )
-        return CE_Failure;
-    const unsigned int nLineBytes = static_cast<unsigned int>(nLineBytesBig);
     const vsi_l_offset nLineStart =
         (nStartBit + nLineOffsetBits * nBlockYOff) / 8;
     int iBitOffset =
         static_cast<int>((nStartBit + nLineOffsetBits * nBlockYOff) % 8);
+    const vsi_l_offset nLineEnd =
+        (nStartBit + nLineOffsetBits * nBlockYOff +
+            static_cast<vsi_l_offset>(nPixelOffsetBits) * nBlockXSize - 1) / 8;
+    const vsi_l_offset nLineBytesBig = nLineEnd - nLineStart + 1;
+    if( nLineBytesBig >
+        static_cast<vsi_l_offset>(std::numeric_limits<int>::max()) )
+        return CE_Failure;
+    const unsigned int nLineBytes = static_cast<unsigned int>(nLineBytesBig);
 
     // Read data into buffer.
     GByte *pabyBuffer = static_cast<GByte *>(VSI_MALLOC_VERBOSE(nLineBytes));
@@ -229,16 +231,18 @@ CPLErr EHdrRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
         return RawRasterBand::IWriteBlock(nBlockXOff, nBlockYOff, pImage);
 
     // Establish desired position.
-    const vsi_l_offset nLineBytesBig =
-        (static_cast<vsi_l_offset>(nPixelOffsetBits) * nBlockXSize + 7) / 8;
-    if( nLineBytesBig >
-        static_cast<vsi_l_offset>(std::numeric_limits<int>::max()) )
-        return CE_Failure;
-    const unsigned int nLineBytes = static_cast<unsigned int>(nLineBytesBig);
     const vsi_l_offset nLineStart =
         (nStartBit + nLineOffsetBits * nBlockYOff) / 8;
     int iBitOffset =
         static_cast<int>((nStartBit + nLineOffsetBits * nBlockYOff) % 8);
+    const vsi_l_offset nLineEnd =
+        (nStartBit + nLineOffsetBits * nBlockYOff +
+            static_cast<vsi_l_offset>(nPixelOffsetBits) * nBlockXSize - 1) / 8;
+    const vsi_l_offset nLineBytesBig = nLineEnd - nLineStart + 1;
+    if( nLineBytesBig >
+        static_cast<vsi_l_offset>(std::numeric_limits<int>::max()) )
+        return CE_Failure;
+    const unsigned int nLineBytes = static_cast<unsigned int>(nLineBytesBig);
 
     // Read data into buffer.
     GByte *pabyBuffer =
diff --git a/frmts/raw/rrasterdataset.cpp b/frmts/raw/rrasterdataset.cpp
index c512a6a..a01e6d1 100644
--- a/frmts/raw/rrasterdataset.cpp
+++ b/frmts/raw/rrasterdataset.cpp
@@ -33,7 +33,7 @@
 #include "rawdataset.h"
 #include "ogr_spatialref.h"
 
-CPL_CVSID("$Id: rrasterdataset.cpp 36682 2016-12-04 20:34:45Z rouault $");
+CPL_CVSID("$Id: rrasterdataset.cpp 41816 2018-03-16 11:33:00Z rouault $");
 
 /************************************************************************/
 /* ==================================================================== */
@@ -509,10 +509,10 @@ GDALDataset *RRASTERDataset::Open( GDALOpenInfo * poOpenInfo )
         poDS->SetBand( i, poBand );
         if( EQUAL(osDataType, "INT1S") )
         {
-            poDS->GetRasterBand(i)->SetMetadataItem(
-                    "SIGNEDBYTE", "PIXELTYPE", "IMAGE_STRUCTURE" );
+            poDS->GetRasterBand(i)->GDALRasterBand::SetMetadataItem(
+                    "PIXELTYPE", "SIGNEDBYTE", "IMAGE_STRUCTURE" );
         }
-        if( !EQUAL(osNoDataValue, "NA") )
+        if( !osNoDataValue.empty() && !EQUAL(osNoDataValue, "NA") )
         {
             double dfNoDataValue = CPLAtof(osNoDataValue);
             poBand->SetNoDataValue(dfNoDataValue);
diff --git a/frmts/sentinel2/sentinel2dataset.cpp b/frmts/sentinel2/sentinel2dataset.cpp
index b469d68..921e149 100644
--- a/frmts/sentinel2/sentinel2dataset.cpp
+++ b/frmts/sentinel2/sentinel2dataset.cpp
@@ -49,7 +49,7 @@
 #define STARTS_WITH_CI(a,b) EQUALN(a,b,strlen(b))
 #endif
 
-CPL_CVSID("$Id: sentinel2dataset.cpp 40547 2017-10-24 17:42:31Z rouault $");
+CPL_CVSID("$Id: sentinel2dataset.cpp 41673 2018-03-09 14:12:44Z rouault $");
 
 CPL_C_START
 // TODO: Leave this declaration while Sentinel2 folks use this as a
@@ -3266,7 +3266,7 @@ SENTINEL2Dataset* SENTINEL2Dataset::CreateL1CL2ADataset(
             }
 
             GDALProxyPoolDataset* proxyDS = NULL;
-            if( bIsPreview )
+            if( bIsPreview || bIsTCI )
             {
                 proxyDS = oMapPVITile[osTile];
                 if( proxyDS == NULL )
@@ -3300,7 +3300,7 @@ SENTINEL2Dataset* SENTINEL2Dataset::CreateL1CL2ADataset(
 
             if( nBand != nAlphaBand )
             {
-                poBand->AddSimpleSource( proxyDS->GetRasterBand((bIsPreview) ? nBand : 1),
+                poBand->AddSimpleSource( proxyDS->GetRasterBand((bIsPreview || bIsTCI) ? nBand : 1),
                                         0, 0,
                                         oGranuleInfo.nWidth,
                                         oGranuleInfo.nHeight,
diff --git a/frmts/vrt/vrtderivedrasterband.cpp b/frmts/vrt/vrtderivedrasterband.cpp
index b138e64..c51a3d1 100644
--- a/frmts/vrt/vrtderivedrasterband.cpp
+++ b/frmts/vrt/vrtderivedrasterband.cpp
@@ -49,7 +49,7 @@
 
 /*! @cond Doxygen_Suppress */
 
-CPL_CVSID("$Id: vrtderivedrasterband.cpp 38039 2017-04-16 13:08:39Z rouault $");
+CPL_CVSID("$Id: vrtderivedrasterband.cpp 41339 2018-01-26 12:21:36Z rouault $");
 
 // #define GDAL_VRT_DISABLE_PYTHON
 // #define PYTHONSO_DEFAULT "libpython2.7.so"
@@ -463,24 +463,27 @@ static bool LoadPythonAPI()
     // First try in the current process in case the python symbols would
     // be already loaded
     HANDLE hProcess = GetCurrentProcess();
-    HMODULE ahModules[100];
+    const size_t nMaxModules = 10000;
+    HMODULE* pahModules = static_cast<HMODULE*>(
+        CPLMalloc(nMaxModules * sizeof(HMODULE)));
     DWORD nSizeNeeded = 0;
 
-    EnumProcessModules(hProcess, ahModules, sizeof(ahModules),
+    EnumProcessModules(hProcess, pahModules, nMaxModules * sizeof(HMODULE),
                         &nSizeNeeded);
 
     const size_t nModules =
-        std::min(size_t(100),
+        std::min(nMaxModules,
                  static_cast<size_t>(nSizeNeeded) / sizeof(HMODULE));
     for( size_t i = 0; i < nModules; i++ )
     {
-        if( GetProcAddress(ahModules[i], "Py_SetProgramName") )
+        if( GetProcAddress(pahModules[i], "Py_SetProgramName") )
         {
-            libHandle = ahModules[i];
+            libHandle = pahModules[i];
             CPLDebug("VRT", "Current process has python symbols loaded");
             break;
         }
     }
+    CPLFree(pahModules);
 
     // Then try the user provided shared object name
     if( libHandle == NULL && pszPythonSO != NULL )
diff --git a/frmts/vrt/vrtrasterband.cpp b/frmts/vrt/vrtrasterband.cpp
index 983b26d..909e926 100644
--- a/frmts/vrt/vrtrasterband.cpp
+++ b/frmts/vrt/vrtrasterband.cpp
@@ -49,7 +49,7 @@
 
 /*! @cond Doxygen_Suppress */
 
-CPL_CVSID("$Id: vrtrasterband.cpp 37310 2017-02-06 11:42:54Z goatbar $");
+CPL_CVSID("$Id: vrtrasterband.cpp 41753 2018-03-12 15:58:55Z rouault $");
 
 /************************************************************************/
 /* ==================================================================== */
@@ -1099,7 +1099,7 @@ GDALRasterBand *VRTRasterBand::GetOverview( int iOverview )
             || iOverview >= static_cast<int>( poVRTDS->m_apoOverviews.size() ) )
             return NULL;
 
-        return poVRTDS->m_apoOverviews[iOverview]->GetRasterBand(nBand);
+        return poVRTDS->m_apoOverviews[iOverview]->GetRasterBand(nBand ? nBand : 1);
     }
 
     return NULL;
diff --git a/gcore/gdal_version.h b/gcore/gdal_version.h
index dd67214..43ca3da 100644
--- a/gcore/gdal_version.h
+++ b/gcore/gdal_version.h
@@ -1,4 +1,4 @@
-/* $Id: gdal_version.h 40767 2017-11-20 10:39:34Z rouault $ */
+/* $Id: gdal_version.h 41865 2018-03-19 12:04:41Z rouault $ */
 
 /* -------------------------------------------------------------------- */
 /*      GDAL Version Information.                                       */
@@ -7,7 +7,7 @@
 #ifndef GDAL_VERSION_MAJOR
 #  define GDAL_VERSION_MAJOR    2
 #  define GDAL_VERSION_MINOR    2
-#  define GDAL_VERSION_REV      3
+#  define GDAL_VERSION_REV      4
 #  define GDAL_VERSION_BUILD    0
 #endif
 
@@ -23,8 +23,8 @@
 #endif
 
 #ifndef GDAL_RELEASE_DATE
-#  define GDAL_RELEASE_DATE     20171120
+#  define GDAL_RELEASE_DATE     20180319
 #endif
 #ifndef GDAL_RELEASE_NAME
-#  define GDAL_RELEASE_NAME     "2.2.3"
+#  define GDAL_RELEASE_NAME     "2.2.4"
 #endif
diff --git a/gnm/gnm_frmts/file/gnmfilenetwork.cpp b/gnm/gnm_frmts/file/gnmfilenetwork.cpp
index f92feaa..6cf9eb5 100644
--- a/gnm/gnm_frmts/file/gnmfilenetwork.cpp
+++ b/gnm/gnm_frmts/file/gnmfilenetwork.cpp
@@ -31,7 +31,7 @@
 #include "gnmfile.h"
 #include "gnm_priv.h"
 
-CPL_CVSID("$Id: gnmfilenetwork.cpp 36741 2016-12-07 16:22:35Z rouault $");
+CPL_CVSID("$Id: gnmfilenetwork.cpp 41303 2018-01-20 18:19:40Z rouault $");
 
 GNMFileNetwork::GNMFileNetwork() : GNMGenericNetwork()
 {
@@ -101,10 +101,10 @@ CPLErr GNMFileNetwork::Open(GDALOpenInfo *poOpenInfo)
     }
 
     m_poLayerDriver = m_pMetadataDS->GetDriver();
-    const char* pszExt = CPLGetExtension(soMetadatafile);
+    CPLString osExt = CPLGetExtension(soMetadatafile);
 
     CPLString soGraphfile = CPLFormFilename(m_soNetworkFullName,
-                                            GNM_SYSLAYER_GRAPH, pszExt);
+                                            GNM_SYSLAYER_GRAPH, osExt);
     m_pGraphDS = (GDALDataset*) GDALOpenEx( soGraphfile, GDAL_OF_VECTOR |
                                             GDAL_OF_UPDATE, NULL, NULL, NULL );
     if( NULL == m_pGraphDS )
@@ -120,7 +120,7 @@ CPLErr GNMFileNetwork::Open(GDALOpenInfo *poOpenInfo)
     }
 
     CPLString soFeaturesfile = CPLFormFilename(m_soNetworkFullName,
-                                            GNM_SYSLAYER_FEATURES, pszExt);
+                                            GNM_SYSLAYER_FEATURES, osExt);
     m_pFeaturesDS = (GDALDataset*) GDALOpenEx( soFeaturesfile, GDAL_OF_VECTOR |
                                                GDAL_OF_UPDATE, NULL, NULL, NULL );
     if( NULL == m_pFeaturesDS )
diff --git a/man/man1/gdal-config.1 b/man/man1/gdal-config.1
index 3a769b2..eb8ba0c 100644
--- a/man/man1/gdal-config.1
+++ b/man/man1/gdal-config.1
@@ -1,4 +1,4 @@
-.TH "gdal-config" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal-config" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal2tiles.1 b/man/man1/gdal2tiles.1
index d0ec106..46c10b5 100644
--- a/man/man1/gdal2tiles.1
+++ b/man/man1/gdal2tiles.1
@@ -1,4 +1,4 @@
-.TH "gdal2tiles" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal2tiles" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_calc.1 b/man/man1/gdal_calc.1
index 1b442f2..c417a65 100644
--- a/man/man1/gdal_calc.1
+++ b/man/man1/gdal_calc.1
@@ -1,4 +1,4 @@
-.TH "gdal_calc" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_calc" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_contour.1 b/man/man1/gdal_contour.1
index cecfa4b..9423104 100644
--- a/man/man1/gdal_contour.1
+++ b/man/man1/gdal_contour.1
@@ -1,4 +1,4 @@
-.TH "gdal_contour" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_contour" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_edit.1 b/man/man1/gdal_edit.1
index ea8db50..a9d7af7 100644
--- a/man/man1/gdal_edit.1
+++ b/man/man1/gdal_edit.1
@@ -1,4 +1,4 @@
-.TH "gdal_edit" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_edit" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_fillnodata.1 b/man/man1/gdal_fillnodata.1
index fc32226..aab4b9c 100644
--- a/man/man1/gdal_fillnodata.1
+++ b/man/man1/gdal_fillnodata.1
@@ -1,4 +1,4 @@
-.TH "gdal_fillnodata" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_fillnodata" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_grid.1 b/man/man1/gdal_grid.1
index 2813153..6e738d9 100644
--- a/man/man1/gdal_grid.1
+++ b/man/man1/gdal_grid.1
@@ -1,4 +1,4 @@
-.TH "gdal_grid" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_grid" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_merge.1 b/man/man1/gdal_merge.1
index 97ad066..8928a5c 100644
--- a/man/man1/gdal_merge.1
+++ b/man/man1/gdal_merge.1
@@ -1,4 +1,4 @@
-.TH "gdal_merge" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_merge" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_pansharpen.1 b/man/man1/gdal_pansharpen.1
index f2e1dae..cbf7c43 100644
--- a/man/man1/gdal_pansharpen.1
+++ b/man/man1/gdal_pansharpen.1
@@ -1,4 +1,4 @@
-.TH "gdal_pansharpen" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_pansharpen" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_polygonize.1 b/man/man1/gdal_polygonize.1
index db8d315..bf31085 100644
--- a/man/man1/gdal_polygonize.1
+++ b/man/man1/gdal_polygonize.1
@@ -1,4 +1,4 @@
-.TH "gdal_polygonize" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_polygonize" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_proximity.1 b/man/man1/gdal_proximity.1
index 6899464..937842d 100644
--- a/man/man1/gdal_proximity.1
+++ b/man/man1/gdal_proximity.1
@@ -1,4 +1,4 @@
-.TH "gdal_proximity" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_proximity" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_rasterize.1 b/man/man1/gdal_rasterize.1
index 8b999b5..27cafc9 100644
--- a/man/man1/gdal_rasterize.1
+++ b/man/man1/gdal_rasterize.1
@@ -1,4 +1,4 @@
-.TH "gdal_rasterize" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_rasterize" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_retile.1 b/man/man1/gdal_retile.1
index 50f0bd1..bde25db 100644
--- a/man/man1/gdal_retile.1
+++ b/man/man1/gdal_retile.1
@@ -1,4 +1,4 @@
-.TH "gdal_retile" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_retile" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_sieve.1 b/man/man1/gdal_sieve.1
index 3bcce49..66999f8 100644
--- a/man/man1/gdal_sieve.1
+++ b/man/man1/gdal_sieve.1
@@ -1,4 +1,4 @@
-.TH "gdal_sieve" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_sieve" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_translate.1 b/man/man1/gdal_translate.1
index 12b29a3..1919864 100644
--- a/man/man1/gdal_translate.1
+++ b/man/man1/gdal_translate.1
@@ -1,4 +1,4 @@
-.TH "gdal_translate" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_translate" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_utilities.1 b/man/man1/gdal_utilities.1
index e47ddf6..055be74 100644
--- a/man/man1/gdal_utilities.1
+++ b/man/man1/gdal_utilities.1
@@ -1,4 +1,4 @@
-.TH "gdal_utilities" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_utilities" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaladdo.1 b/man/man1/gdaladdo.1
index 0e3ab20..276c9f0 100644
--- a/man/man1/gdaladdo.1
+++ b/man/man1/gdaladdo.1
@@ -1,4 +1,4 @@
-.TH "gdaladdo" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaladdo" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalbuildvrt.1 b/man/man1/gdalbuildvrt.1
index dcde627..cd1b9c6 100644
--- a/man/man1/gdalbuildvrt.1
+++ b/man/man1/gdalbuildvrt.1
@@ -1,4 +1,4 @@
-.TH "gdalbuildvrt" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalbuildvrt" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalcompare.1 b/man/man1/gdalcompare.1
index ccce715..2258781 100644
--- a/man/man1/gdalcompare.1
+++ b/man/man1/gdalcompare.1
@@ -1,4 +1,4 @@
-.TH "gdalcompare" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalcompare" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaldem.1 b/man/man1/gdaldem.1
index 4b8f888..f5ba35f 100644
--- a/man/man1/gdaldem.1
+++ b/man/man1/gdaldem.1
@@ -1,4 +1,4 @@
-.TH "gdaldem" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaldem" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalinfo.1 b/man/man1/gdalinfo.1
index da9f0c9..95f3950 100644
--- a/man/man1/gdalinfo.1
+++ b/man/man1/gdalinfo.1
@@ -1,4 +1,4 @@
-.TH "gdalinfo" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalinfo" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdallocationinfo.1 b/man/man1/gdallocationinfo.1
index b6579ce..33976e5 100644
--- a/man/man1/gdallocationinfo.1
+++ b/man/man1/gdallocationinfo.1
@@ -1,4 +1,4 @@
-.TH "gdallocationinfo" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdallocationinfo" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalmanage.1 b/man/man1/gdalmanage.1
index a8f5dac..ffbd553 100644
--- a/man/man1/gdalmanage.1
+++ b/man/man1/gdalmanage.1
@@ -1,4 +1,4 @@
-.TH "gdalmanage" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalmanage" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalmove.1 b/man/man1/gdalmove.1
index b947c92..6f8e793 100644
--- a/man/man1/gdalmove.1
+++ b/man/man1/gdalmove.1
@@ -1,4 +1,4 @@
-.TH "gdalmove" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalmove" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalsrsinfo.1 b/man/man1/gdalsrsinfo.1
index 92d9bdc..19c3d2a 100644
--- a/man/man1/gdalsrsinfo.1
+++ b/man/man1/gdalsrsinfo.1
@@ -1,4 +1,4 @@
-.TH "gdalsrsinfo" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalsrsinfo" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaltindex.1 b/man/man1/gdaltindex.1
index d5f2cdb..e4d85de 100644
--- a/man/man1/gdaltindex.1
+++ b/man/man1/gdaltindex.1
@@ -1,4 +1,4 @@
-.TH "gdaltindex" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaltindex" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaltransform.1 b/man/man1/gdaltransform.1
index 3c732bb..1b689cf 100644
--- a/man/man1/gdaltransform.1
+++ b/man/man1/gdaltransform.1
@@ -1,4 +1,4 @@
-.TH "gdaltransform" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaltransform" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalwarp.1 b/man/man1/gdalwarp.1
index f5dd820..dc2989c 100644
--- a/man/man1/gdalwarp.1
+++ b/man/man1/gdalwarp.1
@@ -1,4 +1,4 @@
-.TH "gdalwarp" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalwarp" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gnm_utilities.1 b/man/man1/gnm_utilities.1
index 1634840..245db24 100644
--- a/man/man1/gnm_utilities.1
+++ b/man/man1/gnm_utilities.1
@@ -1,4 +1,4 @@
-.TH "gnm_utilities" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gnm_utilities" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gnmanalyse.1 b/man/man1/gnmanalyse.1
index 6f05487..06d1cc0 100644
--- a/man/man1/gnmanalyse.1
+++ b/man/man1/gnmanalyse.1
@@ -1,4 +1,4 @@
-.TH "gnmanalyse" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gnmanalyse" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gnmmanage.1 b/man/man1/gnmmanage.1
index b412599..e372f81 100644
--- a/man/man1/gnmmanage.1
+++ b/man/man1/gnmmanage.1
@@ -1,4 +1,4 @@
-.TH "gnmmanage" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "gnmmanage" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/nearblack.1 b/man/man1/nearblack.1
index c5a8ad0..affe712 100644
--- a/man/man1/nearblack.1
+++ b/man/man1/nearblack.1
@@ -1,4 +1,4 @@
-.TH "nearblack" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "nearblack" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogr2ogr.1 b/man/man1/ogr2ogr.1
index 5e9ea3f..676a458 100644
--- a/man/man1/ogr2ogr.1
+++ b/man/man1/ogr2ogr.1
@@ -1,4 +1,4 @@
-.TH "ogr2ogr" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "ogr2ogr" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogr_utilities.1 b/man/man1/ogr_utilities.1
index 56f95ef..29fd850 100644
--- a/man/man1/ogr_utilities.1
+++ b/man/man1/ogr_utilities.1
@@ -1,4 +1,4 @@
-.TH "ogr_utilities" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "ogr_utilities" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrinfo.1 b/man/man1/ogrinfo.1
index d231bb2..6060e4c 100644
--- a/man/man1/ogrinfo.1
+++ b/man/man1/ogrinfo.1
@@ -1,4 +1,4 @@
-.TH "ogrinfo" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrinfo" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrlineref.1 b/man/man1/ogrlineref.1
index 24484b2..03031f2 100644
--- a/man/man1/ogrlineref.1
+++ b/man/man1/ogrlineref.1
@@ -1,4 +1,4 @@
-.TH "ogrlineref" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrlineref" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrmerge.1 b/man/man1/ogrmerge.1
index 8acad88..44c39b7 100644
--- a/man/man1/ogrmerge.1
+++ b/man/man1/ogrmerge.1
@@ -1,4 +1,4 @@
-.TH "ogrmerge" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrmerge" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrtindex.1 b/man/man1/ogrtindex.1
index 61eb0f5..2510d43 100644
--- a/man/man1/ogrtindex.1
+++ b/man/man1/ogrtindex.1
@@ -1,4 +1,4 @@
-.TH "ogrtindex" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrtindex" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/pct2rgb.1 b/man/man1/pct2rgb.1
index e4b30af..3f56a2a 100644
--- a/man/man1/pct2rgb.1
+++ b/man/man1/pct2rgb.1
@@ -1,4 +1,4 @@
-.TH "pct2rgb" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "pct2rgb" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/rgb2pct.1 b/man/man1/rgb2pct.1
index 6acebe7..8cafe7f 100644
--- a/man/man1/rgb2pct.1
+++ b/man/man1/rgb2pct.1
@@ -1,4 +1,4 @@
-.TH "rgb2pct" 1 "Mon Nov 20 2017" "GDAL" \" -*- nroff -*-
+.TH "rgb2pct" 1 "Mon Mar 19 2018" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/ogr/ogrct.cpp b/ogr/ogrct.cpp
index d5c3287..780a8a3 100644
--- a/ogr/ogrct.cpp
+++ b/ogr/ogrct.cpp
@@ -44,7 +44,7 @@
 #include "proj_api.h"
 #endif
 
-CPL_CVSID("$Id: ogrct.cpp 37166 2017-01-17 16:38:53Z rouault $");
+CPL_CVSID("$Id: ogrct.cpp 41301 2018-01-20 17:57:14Z rouault $");
 
 /* ==================================================================== */
 /*      PROJ.4 interface stuff.                                         */
@@ -545,13 +545,13 @@ OGRProj4CT::~OGRProj4CT()
 
     if( pjctx != NULL )
     {
-        pfn_pj_ctx_free(pjctx);
-
         if( psPJSource != NULL )
             pfn_pj_free( psPJSource );
 
         if( psPJTarget != NULL )
             pfn_pj_free( psPJTarget );
+
+        pfn_pj_ctx_free(pjctx);
     }
     else
     {
diff --git a/ogr/ogrgeometry.cpp b/ogr/ogrgeometry.cpp
index b6fceea..71f6027 100644
--- a/ogr/ogrgeometry.cpp
+++ b/ogr/ogrgeometry.cpp
@@ -56,7 +56,7 @@
 #define UNUSED_IF_NO_GEOS
 #endif
 
-CPL_CVSID("$Id: ogrgeometry.cpp 38291 2017-05-14 00:40:31Z rouault $");
+CPL_CVSID("$Id: ogrgeometry.cpp 40911 2017-12-02 15:02:10Z rouault $");
 
 //! @cond Doxygen_Suppress
 int OGRGeometry::bGenerate_DB2_V72_BYTE_ORDER = FALSE;
@@ -5262,6 +5262,8 @@ OGRErr OGRGeometry::PointOnSurfaceInternal( OGRPoint * poPoint ) const
         poPoint->setY( poInsidePoint->getY() );
     }
 
+    OGR_G_DestroyGeometry(hInsidePoint);
+
     return OGRERR_NONE;
 }
 //! @endcond
diff --git a/ogr/ogrsf_frmts/carto/ogr_carto.h b/ogr/ogrsf_frmts/carto/ogr_carto.h
index 95f5a56..c56335f 100644
--- a/ogr/ogrsf_frmts/carto/ogr_carto.h
+++ b/ogr/ogrsf_frmts/carto/ogr_carto.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: ogr_carto.h 36687 2016-12-04 22:28:14Z rouault $
+ * $Id: ogr_carto.h 41751 2018-03-12 15:25:43Z rouault $
  *
  * Project:  CARTO Translator
  * Purpose:  Definition of classes for OGR Carto driver.
@@ -74,7 +74,8 @@ protected:
     bool                 bEOF;
     int                  nFetchedObjects;
     int                  iNextInFetchedObjects;
-    GIntBig              iNext;
+    GIntBig              m_nNextFID;
+    GIntBig              m_nNextOffset;
     json_object         *poCachedObj;
 
     virtual OGRFeature  *GetNextRawFeature();
@@ -94,7 +95,7 @@ protected:
 
     virtual OGRFeatureDefn *    GetLayerDefn() override;
     virtual OGRFeatureDefn *    GetLayerDefnInternal(json_object* poObjIn) = 0;
-    virtual json_object*        FetchNewFeatures(GIntBig iNext);
+    virtual json_object*        FetchNewFeatures();
 
     virtual const char*         GetFIDColumn() override { return osFIDColName.c_str(); }
 
@@ -128,7 +129,7 @@ class OGRCARTOTableLayer : public OGRCARTOLayer
     bool                bInDeferredInsert;
     InsertState         eDeferredInsertState;
     CPLString           osDeferredInsertSQL;
-    GIntBig             nNextFID;
+    GIntBig             m_nNextFIDWrite;
 
     bool                bDeferredCreation;
     bool                bCartodbfy;
@@ -144,7 +145,7 @@ class OGRCARTOTableLayer : public OGRCARTOLayer
 
     virtual const char*         GetName() override { return osName.c_str(); }
     virtual OGRFeatureDefn *    GetLayerDefnInternal(json_object* poObjIn) override;
-    virtual json_object*        FetchNewFeatures(GIntBig iNext) override;
+    virtual json_object*        FetchNewFeatures() override;
 
     virtual GIntBig             GetFeatureCount( int bForce = TRUE ) override;
     virtual OGRFeature         *GetFeature( GIntBig nFeatureId ) override;
diff --git a/ogr/ogrsf_frmts/carto/ogrcartolayer.cpp b/ogr/ogrsf_frmts/carto/ogrcartolayer.cpp
index a212024..2ee9424 100644
--- a/ogr/ogrsf_frmts/carto/ogrcartolayer.cpp
+++ b/ogr/ogrsf_frmts/carto/ogrcartolayer.cpp
@@ -30,7 +30,7 @@
 #include "ogr_p.h"
 #include "ogrgeojsonreader.h"
 
-CPL_CVSID("$Id: ogrcartolayer.cpp 37371 2017-02-13 11:41:59Z rouault $");
+CPL_CVSID("$Id: ogrcartolayer.cpp 41751 2018-03-12 15:25:43Z rouault $");
 
 /************************************************************************/
 /*                         OGRCARTOLayer()                            */
@@ -71,7 +71,8 @@ void OGRCARTOLayer::ResetReading()
     bEOF = false;
     nFetchedObjects = -1;
     iNextInFetchedObjects = 0;
-    iNext = 0;
+    m_nNextOffset = 0;
+    m_nNextFID = 0;
 }
 
 /************************************************************************/
@@ -107,7 +108,7 @@ OGRFeature *OGRCARTOLayer::BuildFeature(json_object* poRowObj)
         }
         else
         {
-            poFeature->SetFID(iNext);
+            poFeature->SetFID(m_nNextFID);
         }
 
         for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
@@ -168,7 +169,7 @@ OGRFeature *OGRCARTOLayer::BuildFeature(json_object* poRowObj)
 /*                        FetchNewFeatures()                            */
 /************************************************************************/
 
-json_object* OGRCARTOLayer::FetchNewFeatures(GIntBig iNextIn)
+json_object* OGRCARTOLayer::FetchNewFeatures()
 {
     CPLString osSQL = osBaseSQL;
     if( osSQL.ifind("SELECT") != std::string::npos &&
@@ -177,7 +178,7 @@ json_object* OGRCARTOLayer::FetchNewFeatures(GIntBig iNextIn)
         osSQL += " LIMIT ";
         osSQL += CPLSPrintf("%d", GetFeaturesToFetch());
         osSQL += " OFFSET ";
-        osSQL += CPLSPrintf(CPL_FRMT_GIB, iNextIn);
+        osSQL += CPLSPrintf(CPL_FRMT_GIB, m_nNextOffset);
     }
     return poDS->RunSQL(osSQL);
 }
@@ -204,7 +205,7 @@ OGRFeature *OGRCARTOLayer::GetNextRawFeature()
             GetLayerDefn();
         }
 
-        json_object* poObj = FetchNewFeatures(iNext);
+        json_object* poObj = FetchNewFeatures();
         if( poObj == NULL )
         {
             bEOF = true;
@@ -240,7 +241,8 @@ OGRFeature *OGRCARTOLayer::GetNextRawFeature()
     iNextInFetchedObjects ++;
 
     OGRFeature* poFeature = BuildFeature(poRowObj);
-    iNext = poFeature->GetFID() + 1;
+    m_nNextOffset ++;
+    m_nNextFID = poFeature->GetFID() + 1;
 
     return poFeature;
 }
diff --git a/ogr/ogrsf_frmts/carto/ogrcartotablelayer.cpp b/ogr/ogrsf_frmts/carto/ogrcartotablelayer.cpp
index 07836da..d0e2f95 100644
--- a/ogr/ogrsf_frmts/carto/ogrcartotablelayer.cpp
+++ b/ogr/ogrsf_frmts/carto/ogrcartotablelayer.cpp
@@ -31,7 +31,7 @@
 #include "ogr_pgdump.h"
 #include "ogrgeojsonreader.h"
 
-CPL_CVSID("$Id: ogrcartotablelayer.cpp 37371 2017-02-13 11:41:59Z rouault $");
+CPL_CVSID("$Id: ogrcartotablelayer.cpp 41751 2018-03-12 15:25:43Z rouault $");
 
 /************************************************************************/
 /*                    OGRCARTOEscapeIdentifier( )                     */
@@ -88,7 +88,7 @@ OGRCARTOTableLayer::OGRCARTOTableLayer(OGRCARTODataSource* poDSIn,
     bLaunderColumnNames = true;
     bInDeferredInsert = poDS->DoBatchInsert();
     eDeferredInsertState = INSERT_UNINIT;
-    nNextFID = -1;
+    m_nNextFIDWrite = -1;
     bDeferredCreation = false;
     bCartodbfy = false;
     nMaxChunkSize = atoi(CPLGetConfigOption("CARTO_MAX_CHUNK_SIZE",
@@ -311,7 +311,7 @@ OGRFeatureDefn * OGRCARTOTableLayer::GetLayerDefnInternal(CPL_UNUSED json_object
 /*                        FetchNewFeatures()                            */
 /************************************************************************/
 
-json_object* OGRCARTOTableLayer::FetchNewFeatures(GIntBig iNextIn)
+json_object* OGRCARTOTableLayer::FetchNewFeatures()
 {
     if( !osFIDColName.empty() )
     {
@@ -320,13 +320,13 @@ json_object* OGRCARTOTableLayer::FetchNewFeatures(GIntBig iNextIn)
                      osSELECTWithoutWHERE.c_str(),
                      ( osWHERE.size() ) ? CPLSPrintf("%s AND ", osWHERE.c_str()) : "",
                      OGRCARTOEscapeIdentifier(osFIDColName).c_str(),
-                     iNext,
+                     m_nNextFID,
                      OGRCARTOEscapeIdentifier(osFIDColName).c_str(),
                      GetFeaturesToFetch());
         return poDS->RunSQL(osSQL);
     }
     else
-        return OGRCARTOLayer::FetchNewFeatures(iNextIn);
+        return OGRCARTOLayer::FetchNewFeatures();
 }
 
 /************************************************************************/
@@ -454,7 +454,7 @@ OGRErr OGRCARTOTableLayer::FlushDeferredInsert(bool bReset)
     if( bReset )
     {
         bInDeferredInsert = false;
-        nNextFID = -1;
+        m_nNextFIDWrite = -1;
     }
     return eErr;
 }
@@ -591,32 +591,53 @@ OGRErr OGRCARTOTableLayer::ICreateFeature( OGRFeature *poFeature )
     CPLString osSQL;
 
     bool bHasJustGotNextFID = false;
-    if( !bHasUserFieldMatchingFID && bInDeferredInsert && nNextFID < 0 && !osFIDColName.empty() )
+    if( !bHasUserFieldMatchingFID && bInDeferredInsert && m_nNextFIDWrite < 0 && !osFIDColName.empty() )
     {
-        osSQL.Printf("SELECT nextval('%s') AS nextid",
-                     OGRCARTOEscapeLiteral(CPLSPrintf("%s_%s_seq", osName.c_str(), osFIDColName.c_str())).c_str());
-
+        CPLString osSeqName;
+        osSQL.Printf("SELECT pg_catalog.pg_get_serial_sequence('%s', '%s') AS seq_name",
+                     OGRCARTOEscapeLiteral(osName).c_str(),
+                     OGRCARTOEscapeLiteral(osFIDColName).c_str());
         json_object* poObj = poDS->RunSQL(osSQL);
         json_object* poRowObj = OGRCARTOGetSingleRow(poObj);
         if( poRowObj != NULL )
         {
-            json_object* poID = CPL_json_object_object_get(poRowObj, "nextid");
-            if( poID != NULL && json_object_get_type(poID) == json_type_int )
+            json_object* poSeqName = CPL_json_object_object_get(poRowObj, "seq_name");
+            if( poSeqName != NULL && json_object_get_type(poSeqName) == json_type_string )
             {
-                nNextFID = json_object_get_int64(poID);
-                bHasJustGotNextFID = true;
+                osSeqName = json_object_get_string(poSeqName);
             }
         }
 
         if( poObj != NULL )
             json_object_put(poObj);
+
+        if( !osSeqName.empty() )
+        {
+            osSQL.Printf("SELECT nextval('%s') AS nextid",
+                        OGRCARTOEscapeLiteral(osSeqName).c_str());
+
+            poObj = poDS->RunSQL(osSQL);
+            poRowObj = OGRCARTOGetSingleRow(poObj);
+            if( poRowObj != NULL )
+            {
+                json_object* poID = CPL_json_object_object_get(poRowObj, "nextid");
+                if( poID != NULL && json_object_get_type(poID) == json_type_int )
+                {
+                    m_nNextFIDWrite = json_object_get_int64(poID);
+                    bHasJustGotNextFID = true;
+                }
+            }
+
+            if( poObj != NULL )
+                json_object_put(poObj);
+        }
     }
 
     // Check if we can go on with multiple insertion mode
     if( eDeferredInsertState == INSERT_MULTIPLE_FEATURE )
     {
         if( !bHasUserFieldMatchingFID && !osFIDColName.empty() &&
-            (poFeature->GetFID() != OGRNullFID || (nNextFID >= 0 && bHasJustGotNextFID)) )
+            (poFeature->GetFID() != OGRNullFID || (m_nNextFIDWrite >= 0 && bHasJustGotNextFID)) )
         {
             if( FlushDeferredInsert(false) != OGRERR_NONE )
                 return OGRERR_FAILURE;
@@ -632,7 +653,7 @@ OGRErr OGRCARTOTableLayer::ICreateFeature( OGRFeature *poFeature )
             eDeferredInsertState = INSERT_SINGLE_FEATURE;
         }
         else if( !bHasUserFieldMatchingFID && !osFIDColName.empty() &&
-            (poFeature->GetFID() != OGRNullFID || (nNextFID >= 0 && bHasJustGotNextFID)) )
+            (poFeature->GetFID() != OGRNullFID || (m_nNextFIDWrite >= 0 && bHasJustGotNextFID)) )
         {
             eDeferredInsertState = INSERT_SINGLE_FEATURE;
             bResetToUninitInsertStateAfterwards = true;
@@ -687,7 +708,7 @@ OGRErr OGRCARTOTableLayer::ICreateFeature( OGRFeature *poFeature )
         }
 
         if( !bHasUserFieldMatchingFID &&
-            !osFIDColName.empty() && (poFeature->GetFID() != OGRNullFID || (nNextFID >= 0 && bHasJustGotNextFID)) )
+            !osFIDColName.empty() && (poFeature->GetFID() != OGRNullFID || (m_nNextFIDWrite >= 0 && bHasJustGotNextFID)) )
         {
             if( bMustComma )
                 osSQL += ", ";
@@ -801,20 +822,9 @@ OGRErr OGRCARTOTableLayer::ICreateFeature( OGRFeature *poFeature )
             CPLFree(pszEWKB);
         }
 
-        if( !bHasUserFieldMatchingFID )
+        if( bWriteInsertInto && !bHasUserFieldMatchingFID && !osFIDColName.empty() )
         {
-            if( !osFIDColName.empty() && nNextFID >= 0 )
-            {
-                if( bHasJustGotNextFID )
-                {
-                    if( bMustComma )
-                        osSQL += ", ";
-                    // No need to set bMustComma to true in else case.
-                    // Not in a loop.
-                    osSQL += CPLSPrintf(CPL_FRMT_GIB, nNextFID);
-                }
-            }
-            else if( !osFIDColName.empty() && poFeature->GetFID() != OGRNullFID )
+            if( poFeature->GetFID() != OGRNullFID )
             {
                 if( bMustComma )
                     osSQL += ", ";
@@ -823,15 +833,24 @@ OGRErr OGRCARTOTableLayer::ICreateFeature( OGRFeature *poFeature )
 
                 osSQL += CPLSPrintf(CPL_FRMT_GIB, poFeature->GetFID());
             }
+            else if( m_nNextFIDWrite >= 0 && bHasJustGotNextFID )
+            {
+                if( bMustComma )
+                    osSQL += ", ";
+                // No need to set bMustComma to true in else case.
+                // Not in a loop.
+                osSQL += CPLSPrintf(CPL_FRMT_GIB, m_nNextFIDWrite);
+            }
         }
 
         osSQL += ")";
     }
 
-    if( !bHasUserFieldMatchingFID && !osFIDColName.empty() && nNextFID >= 0 )
+    if( !bHasUserFieldMatchingFID && !osFIDColName.empty() && m_nNextFIDWrite >= 0 &&
+        poFeature->GetFID() == OGRNullFID )
     {
-        poFeature->SetFID(nNextFID);
-        nNextFID ++;
+        poFeature->SetFID(m_nNextFIDWrite);
+        m_nNextFIDWrite ++;
     }
 
     if( bInDeferredInsert )
@@ -1384,7 +1403,7 @@ void OGRCARTOTableLayer::SetDeferredCreation( OGRwkbGeometryType eGType,
                                               bool bCartodbfyIn )
 {
     bDeferredCreation = true;
-    nNextFID = 1;
+    m_nNextFIDWrite = 1;
     CPLAssert(poFeatureDefn == NULL);
     bCartodbfy = bCartodbfyIn;
     poFeatureDefn = new OGRFeatureDefn(osName);
diff --git a/ogr/ogrsf_frmts/geojson/ogrgeojsonwritelayer.cpp b/ogr/ogrsf_frmts/geojson/ogrgeojsonwritelayer.cpp
index 62b8c9f..4900825 100644
--- a/ogr/ogrsf_frmts/geojson/ogrgeojsonwritelayer.cpp
+++ b/ogr/ogrsf_frmts/geojson/ogrgeojsonwritelayer.cpp
@@ -32,7 +32,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: ogrgeojsonwritelayer.cpp 37472 2017-02-26 02:47:45Z goatbar $");
+CPL_CVSID("$Id: ogrgeojsonwritelayer.cpp 41192 2018-01-04 18:37:00Z rouault $");
 
 // Remove annoying warnings Microsoft Visual C++.
 #if defined(_MSC_VER)
@@ -151,6 +151,7 @@ OGRErr OGRGeoJSONWriteLayer::ICreateFeature( OGRFeature* poFeature )
     {
         poFeatureToWrite = new OGRFeature(poFeatureDefn_);
         poFeatureToWrite->SetFrom( poFeature );
+        poFeatureToWrite->SetFID( poFeature->GetFID() );
         OGRGeometry* poGeometry = poFeatureToWrite->GetGeometryRef();
         if( poGeometry )
         {
diff --git a/ogr/ogrsf_frmts/geojson/ogrgeojsonwriter.cpp b/ogr/ogrsf_frmts/geojson/ogrgeojsonwriter.cpp
index ef5d281..3dc8db6 100644
--- a/ogr/ogrsf_frmts/geojson/ogrgeojsonwriter.cpp
+++ b/ogr/ogrsf_frmts/geojson/ogrgeojsonwriter.cpp
@@ -27,17 +27,23 @@
  * DEALINGS IN THE SOFTWARE.
  ****************************************************************************/
 
+#define JSON_C_VER_013 (13 << 8)
+
 #include "ogrgeojsonwriter.h"
 #include "ogrgeojsonutils.h"
 #include "ogr_geojson.h"
 #include "ogrgeojsonreader.h"
 #include <json.h>  // JSON-C
+
+#if (!defined(JSON_C_VERSION_NUM)) || (JSON_C_VERSION_NUM < JSON_C_VER_013)
 #include <json_object_private.h>
+#endif
+
 #include <printbuf.h>
 #include <ogr_api.h>
 #include <ogr_p.h>
 
-CPL_CVSID("$Id: ogrgeojsonwriter.cpp 39217 2017-06-20 20:43:30Z rouault $");
+CPL_CVSID("$Id: ogrgeojsonwriter.cpp 41200 2018-01-05 18:08:49Z rouault $");
 
 
 /************************************************************************/
@@ -1381,13 +1387,17 @@ static int OGR_json_double_with_precision_to_string( struct json_object *jso,
 {
     // TODO(schwehr): Explain this casting.
     const int nPrecision =
+#if (!defined(JSON_C_VERSION_NUM)) || (JSON_C_VERSION_NUM < JSON_C_VER_013)
         static_cast<int>(reinterpret_cast<GUIntptr_t>(jso->_userdata));
+#else
+        static_cast<int>(reinterpret_cast<GUIntptr_t>(json_object_get_userdata(jso)));
+#endif
     char szBuffer[75] = {};
-    OGRFormatDouble( szBuffer, sizeof(szBuffer), jso->o.c_double, '.',
+    OGRFormatDouble( szBuffer, sizeof(szBuffer), json_object_get_double(jso), '.',
                      (nPrecision < 0) ? 15 : nPrecision );
     if( szBuffer[0] == 't' /*oobig */ )
     {
-        CPLsnprintf(szBuffer, sizeof(szBuffer), "%.18g", jso->o.c_double);
+        CPLsnprintf(szBuffer, sizeof(szBuffer), "%.18g", json_object_get_double(jso));
     }
     return printbuf_memappend(pb, szBuffer, static_cast<int>(strlen(szBuffer)));
 }
@@ -1417,11 +1427,11 @@ OGR_json_double_with_significant_figures_to_string( struct json_object *jso,
 {
     char szBuffer[75] = {};
     int nSize = 0;
-    if( CPLIsNan(jso->o.c_double))
+    if( CPLIsNan(json_object_get_double(jso)))
         nSize = CPLsnprintf(szBuffer, sizeof(szBuffer), "NaN");
-    else if( CPLIsInf(jso->o.c_double) )
+    else if( CPLIsInf(json_object_get_double(jso)) )
     {
-        if( jso->o.c_double > 0 )
+        if( json_object_get_double(jso) > 0 )
             nSize = CPLsnprintf(szBuffer, sizeof(szBuffer), "Infinity");
         else
             nSize = CPLsnprintf(szBuffer, sizeof(szBuffer), "-Infinity");
@@ -1429,13 +1439,17 @@ OGR_json_double_with_significant_figures_to_string( struct json_object *jso,
     else
     {
         char szFormatting[32] = {};
+#if (!defined(JSON_C_VERSION_NUM)) || (JSON_C_VERSION_NUM < JSON_C_VER_013)
         const int nSignificantFigures = (int) (GUIntptr_t) jso->_userdata;
+#else
+        const int nSignificantFigures = (int) (GUIntptr_t) json_object_get_userdata(jso);
+#endif
         const int nInitialSignificantFigures =
             nSignificantFigures >= 0 ? nSignificantFigures : 17;
         CPLsnprintf(szFormatting, sizeof(szFormatting),
                     "%%.%dg", nInitialSignificantFigures);
         nSize = CPLsnprintf(szBuffer, sizeof(szBuffer),
-                            szFormatting, jso->o.c_double);
+                            szFormatting, json_object_get_double(jso));
         const char* pszDot = NULL;
         if( nSize+2 < static_cast<int>(sizeof(szBuffer)) &&
             (pszDot = strchr(szBuffer, '.')) == NULL )
@@ -1457,7 +1471,7 @@ OGR_json_double_with_significant_figures_to_string( struct json_object *jso,
                 CPLsnprintf(szFormatting, sizeof(szFormatting),
                             "%%.%dg", nInitialSignificantFigures- i);
                 nSize = CPLsnprintf(szBuffer, sizeof(szBuffer),
-                                    szFormatting, jso->o.c_double);
+                                    szFormatting, json_object_get_double(jso));
                 pszDot = strchr(szBuffer, '.');
                 if( pszDot != NULL &&
                     strstr(pszDot, "999999") == NULL &&
@@ -1472,7 +1486,7 @@ OGR_json_double_with_significant_figures_to_string( struct json_object *jso,
                 CPLsnprintf(szFormatting, sizeof(szFormatting),
                             "%%.%dg", nInitialSignificantFigures);
                 nSize = CPLsnprintf(szBuffer, sizeof(szBuffer),
-                                    szFormatting, jso->o.c_double);
+                                    szFormatting, json_object_get_double(jso));
                 if( nSize+2 < static_cast<int>(sizeof(szBuffer)) &&
                     strchr(szBuffer, '.') == NULL )
                 {
diff --git a/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp b/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp
index 288735c..fce9529 100644
--- a/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp
+++ b/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp
@@ -33,7 +33,7 @@
 #include "cpl_time.h"
 #include "ogr_p.h"
 
-CPL_CVSID("$Id: ogrgeopackagetablelayer.cpp 40670 2017-11-09 15:24:07Z rouault $");
+CPL_CVSID("$Id: ogrgeopackagetablelayer.cpp 41766 2018-03-13 09:21:58Z rouault $");
 
 static const char UNSUPPORTED_OP_READ_ONLY[] =
   "%s : unsupported operation on a read-only datasource.";
@@ -2598,7 +2598,7 @@ bool OGRGeoPackageTableLayer::CreateSpatialIndex(const char* pszTableName)
         Actions   : Remove record from rtree for old <i>
                     Insert record into rtree for new <i> */
     pszSQL = sqlite3_mprintf(
-                   "CREATE TRIGGER \"%w_update3\" AFTER UPDATE OF \"%w\" ON \"%w\" "
+                   "CREATE TRIGGER \"%w_update3\" AFTER UPDATE ON \"%w\" "
                    "WHEN OLD.\"%w\" != NEW.\"%w\" AND "
                    "(NEW.\"%w\" NOTNULL AND NOT ST_IsEmpty(NEW.\"%w\")) "
                    "BEGIN "
@@ -2609,7 +2609,7 @@ bool OGRGeoPackageTableLayer::CreateSpatialIndex(const char* pszTableName)
                    "ST_MinY(NEW.\"%w\"), ST_MaxY(NEW.\"%w\")"
                    "); "
                    "END",
-                   m_osRTreeName.c_str(), pszC, pszT,
+                   m_osRTreeName.c_str(), pszT,
                    pszI, pszI,
                    pszC, pszC,
                    m_osRTreeName.c_str(), pszI,
diff --git a/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp b/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp
index 7acab55..97567b9 100644
--- a/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp
+++ b/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp
@@ -35,7 +35,7 @@
 #include "ogr_p.h"
 #include "cpl_vsi_error.h"
 
-CPL_CVSID("$Id: ogrlibkmldatasource.cpp 39692 2017-07-30 19:32:43Z rouault $");
+CPL_CVSID("$Id: ogrlibkmldatasource.cpp 41434 2018-02-07 13:47:57Z rouault $");
 
 using kmlbase::Attributes;
 using kmldom::ContainerPtr;
@@ -137,6 +137,46 @@ static void OGRLIBKMLPreProcessInput( std::string& oKml )
         }
         oKml[nPos+2] = 'S';
     }
+
+    // Workaround Windows specific issue with libkml (at least the version
+    // used by OSGeo4W at time of writing), where tabulations as
+    // coordinate separators aren't properly handled
+    //(see https://trac.osgeo.org/gdal/ticket/7231)
+    // Another Windows specific issue is that if the content of
+    // <coordinates> is non-empty and does not contain any digit,
+    // libkml hangs (see https://trac.osgeo.org/gdal/ticket/7232)
+    nPos = 0;
+    while( true )
+    {
+        nPos = oKml.find("<coordinates>", nPos);
+        if( nPos == std::string::npos )
+        {
+            break;
+        }
+        size_t nPosEnd = oKml.find("</coordinates>", nPos);
+        if( nPosEnd == std::string::npos )
+        {
+            break;
+        }
+        nPos += strlen("<coordinates>");
+        size_t nPosAfterCoordinates = nPos;
+        bool bDigitFound = false;
+        for( ; nPos < nPosEnd; nPos++ )
+        {
+            if( oKml[nPos] >= '0' && oKml[nPos] <= '9' )
+                bDigitFound = true;
+            else if( oKml[nPos] == '\t' )
+                oKml[nPos] = ' ';
+        }
+        if( !bDigitFound )
+        {
+            oKml.replace(nPosAfterCoordinates,
+                         nPosEnd + strlen("</coordinates>") -
+                                nPosAfterCoordinates,
+                         "</coordinates>");
+            nPos = nPosAfterCoordinates + strlen("</coordinates>");
+        }
+    }
 }
 
 /************************************************************************/
diff --git a/ogr/ogrsf_frmts/mitab/mitab_spatialref.cpp b/ogr/ogrsf_frmts/mitab/mitab_spatialref.cpp
index b7e6e66..2985b9a 100644
--- a/ogr/ogrsf_frmts/mitab/mitab_spatialref.cpp
+++ b/ogr/ogrsf_frmts/mitab/mitab_spatialref.cpp
@@ -45,7 +45,7 @@
 #include "ogr_spatialref.h"
 #include "ogr_srs_api.h"
 
-CPL_CVSID("$Id: mitab_spatialref.cpp 38702 2017-05-30 21:46:38Z rouault $");
+CPL_CVSID("$Id: mitab_spatialref.cpp 41774 2018-03-13 14:25:48Z rouault $");
 
 /* -------------------------------------------------------------------- */
 /*      This table was automatically generated by doing translations    */
@@ -100,6 +100,7 @@ const MapInfoDatumInfo asDatumInfoList[] =
 { 0,    32, "GRS_67",                      21,0,    0,    0,   0, 0, 0, 0, 0},
 { 0,    33, "GRS_80",                      0, 0,    0,    0,   0, 0, 0, 0, 0},
 { 6171, 33, "Reseau_Geodesique_Francais_1993",0, 0, 0,    0,   0, 0, 0, 0, 0},
+{ 6619, 33, "SWEREF99",                    0, 0,    0,    0,   0, 0, 0, 0, 0},
 { 6675, 34, "Guam_1963",                   7, -100, -248, 259, 0, 0, 0, 0, 0},
 { 0,    35, "Gux_1_Astro",                 4, 252,  -209, -751,0, 0, 0, 0, 0},
 { 6254, 36, "Hito_XVIII_1963",             4, 16,   196,  93,  0, 0, 0, 0, 0},
diff --git a/ogr/ogrsf_frmts/mitab/mitab_tabview.cpp b/ogr/ogrsf_frmts/mitab/mitab_tabview.cpp
index 4dd5fc4..0bf9845 100644
--- a/ogr/ogrsf_frmts/mitab/mitab_tabview.cpp
+++ b/ogr/ogrsf_frmts/mitab/mitab_tabview.cpp
@@ -50,7 +50,7 @@
 #include "ogr_geometry.h"
 #include "ogr_spatialref.h"
 
-CPL_CVSID("$Id: mitab_tabview.cpp 37351 2017-02-12 05:22:20Z goatbar $");
+CPL_CVSID("$Id: mitab_tabview.cpp 40965 2017-12-06 13:41:33Z rouault $");
 
 /*=====================================================================
  *                      class TABView
@@ -1324,6 +1324,7 @@ int  TABRelation::Init(const char *pszViewName,
     /*-----------------------------------------------------------------
      * If selectedFields = "*" then select all fields from both tables
      *----------------------------------------------------------------*/
+    papszSelectedFields = CSLDuplicate(papszSelectedFields);
     if (CSLCount(papszSelectedFields) == 1 &&
         EQUAL(papszSelectedFields[0], "*") )
     {
diff --git a/ogr/ogrsf_frmts/nas/nashandler.cpp b/ogr/ogrsf_frmts/nas/nashandler.cpp
index bf44b01..facce63 100644
--- a/ogr/ogrsf_frmts/nas/nashandler.cpp
+++ b/ogr/ogrsf_frmts/nas/nashandler.cpp
@@ -33,7 +33,7 @@
 #include "cpl_string.h"
 #include "ogr_xerces.h"
 
-CPL_CVSID("$Id: nashandler.cpp 39560 2017-07-12 08:53:28Z rouault $");
+CPL_CVSID("$Id: nashandler.cpp 41855 2018-03-17 16:03:50Z rouault $");
 
 /*
   Update modes:
@@ -517,26 +517,28 @@ void NASHandler::endElement( const XMLCh* const /* uri */ ,
    {
        if( m_osElementName == "Name" && m_nDepth == m_nNameOrValueDepth )
        {
-           CPLAssert( m_osLastPropertyName == "" );
-           m_osLastPropertyName = m_pszCurField;
+           m_osLastPropertyName = m_pszCurField ? m_pszCurField : "";
+           CPLFree(m_pszCurField);
            m_pszCurField = NULL;
            m_nNameOrValueDepth = 0;
        }
        else if( m_osElementName == "Value" && m_nDepth == m_nNameOrValueDepth )
        {
-           CPLAssert( m_osLastPropertyValue == "" );
-           m_osLastPropertyValue = m_pszCurField;
+           m_osLastPropertyValue = m_pszCurField ? m_pszCurField : "";
+           CPLFree(m_pszCurField);
            m_pszCurField = NULL;
            m_nNameOrValueDepth = 0;
        }
        else if( m_nDepth == m_nUpdatePropertyDepth && m_osElementName == "Property" )
        {
-           if( EQUAL( m_osLastPropertyName, "adv:lebenszeitintervall/adv:AA_Lebenszeitintervall/adv:endet" ) )
+           if( EQUAL( m_osLastPropertyName, "adv:lebenszeitintervall/adv:AA_Lebenszeitintervall/adv:endet" ) ||
+               EQUAL( m_osLastPropertyName, "lebenszeitintervall/AA_Lebenszeitintervall/endet" ) )
            {
                CPLAssert( m_osLastPropertyValue != "" );
                m_osLastEnded = m_osLastPropertyValue;
            }
-           else if( EQUAL( m_osLastPropertyName, "adv:anlass" ) )
+           else if( EQUAL( m_osLastPropertyName, "adv:anlass" ) ||
+                    EQUAL( m_osLastPropertyName, "anlass" ) )
            {
                CPLAssert( m_osLastPropertyValue != "" );
                m_LastOccasions.push_back( m_osLastPropertyValue );
diff --git a/ogr/ogrsf_frmts/ntf/ntffilereader.cpp b/ogr/ogrsf_frmts/ntf/ntffilereader.cpp
index 303b877..03503c6 100644
--- a/ogr/ogrsf_frmts/ntf/ntffilereader.cpp
+++ b/ogr/ogrsf_frmts/ntf/ntffilereader.cpp
@@ -35,7 +35,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: ntffilereader.cpp 39006 2017-06-09 07:55:52Z rouault $");
+CPL_CVSID("$Id: ntffilereader.cpp 41289 2018-01-18 11:46:21Z rouault $");
 
 static int DefaultNTFRecordGrouper( NTFFileReader *, NTFRecord **,
                                     NTFRecord * );
@@ -951,7 +951,7 @@ int NTFFileReader::ProcessAttRec( NTFRecord * poRecord,
             iOffset = nEnd;
             if( iOffset >= poRecord->GetLength() )
             {
-                bError = true;
+                bError = (iOffset > poRecord->GetLength());
                 break;
             }
             if( pszData[iOffset] == '\\' )
diff --git a/ogr/ogrsf_frmts/odbc/ogrodbctablelayer.cpp b/ogr/ogrsf_frmts/odbc/ogrodbctablelayer.cpp
index 3ffeaa5..7bd8ada 100644
--- a/ogr/ogrsf_frmts/odbc/ogrodbctablelayer.cpp
+++ b/ogr/ogrsf_frmts/odbc/ogrodbctablelayer.cpp
@@ -30,7 +30,7 @@
 #include "cpl_conv.h"
 #include "ogr_odbc.h"
 
-CPL_CVSID("$Id: ogrodbctablelayer.cpp 35911 2016-10-24 15:03:26Z goatbar $");
+CPL_CVSID("$Id: ogrodbctablelayer.cpp 41671 2018-03-09 14:03:10Z rouault $");
 /************************************************************************/
 /*                          OGRODBCTableLayer()                         */
 /************************************************************************/
@@ -211,6 +211,32 @@ CPLODBCStatement *OGRODBCTableLayer::GetStatement()
 }
 
 /************************************************************************/
+/*                      EscapeAndQuoteIdentifier()                      */
+/************************************************************************/
+
+static CPLString EscapeAndQuoteIdentifier(const CPLString& osStr)
+{
+    CPLString osRet; int num_dots = 0;
+    for( size_t i = 0; i < osStr.size(); i++ )
+    {
+        if( osStr[i] == '"' )
+        {
+            osRet += "\\\"";
+        }
+        else if (osStr[i] == '.' && num_dots == 0){
+            /* It's schema qualified, so first segment we assume is the schema and should be quoted separately */
+            osRet += "\".\"";
+            num_dots += 1;
+        }
+        else
+        {
+            osRet += osStr[i];
+        }
+    }
+    return '"' + osRet + '"';
+}
+
+/************************************************************************/
 /*                           ResetStatement()                           */
 /************************************************************************/
 
@@ -223,7 +249,7 @@ OGRErr OGRODBCTableLayer::ResetStatement()
 
     poStmt = new CPLODBCStatement( poDS->GetSession() );
     poStmt->Append( "SELECT * FROM " );
-    poStmt->Append( poFeatureDefn->GetName() );
+    poStmt->Append( EscapeAndQuoteIdentifier(poFeatureDefn->GetName()) );
 
     /* Append attribute query if we have it */
     if( pszQuery != NULL )
@@ -281,8 +307,10 @@ OGRFeature *OGRODBCTableLayer::GetFeature( GIntBig nFeatureId )
 
     poStmt = new CPLODBCStatement( poDS->GetSession() );
     poStmt->Append( "SELECT * FROM " );
-    poStmt->Append( poFeatureDefn->GetName() );
-    poStmt->Appendf( " WHERE %s = " CPL_FRMT_GIB, pszFIDColumn, nFeatureId );
+    poStmt->Append( EscapeAndQuoteIdentifier(poFeatureDefn->GetName()) );
+    poStmt->Appendf( " WHERE %s = " CPL_FRMT_GIB,
+                     EscapeAndQuoteIdentifier(pszFIDColumn).c_str(),
+                     nFeatureId );
 
     if( !poStmt->ExecuteSQL() )
     {
@@ -348,7 +376,7 @@ GIntBig OGRODBCTableLayer::GetFeatureCount( int bForce )
 
     CPLODBCStatement oStmt( poDS->GetSession() );
     oStmt.Append( "SELECT COUNT(*) FROM " );
-    oStmt.Append( poFeatureDefn->GetName() );
+    oStmt.Append( EscapeAndQuoteIdentifier(poFeatureDefn->GetName()) );
 
     if( pszQuery != NULL )
         oStmt.Appendf( " WHERE %s", pszQuery );
diff --git a/ogr/ogrsf_frmts/shape/dbfopen.c b/ogr/ogrsf_frmts/shape/dbfopen.c
index 68d1172..caabc55 100644
--- a/ogr/ogrsf_frmts/shape/dbfopen.c
+++ b/ogr/ogrsf_frmts/shape/dbfopen.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: dbfopen.c 37046 2016-12-31 09:59:57Z rouault $
+ * $Id: dbfopen.c 41846 2018-03-17 13:27:51Z rouault $
  *
  * Project:  Shapelib
  * Purpose:  Implementation of .dbf access API documented in dbf_api.html.
@@ -209,7 +209,7 @@
 #define CPLsnprintf snprintf
 #endif
 
-SHP_CVSID("$Id: dbfopen.c 37046 2016-12-31 09:59:57Z rouault $")
+SHP_CVSID("$Id: dbfopen.c 41846 2018-03-17 13:27:51Z rouault $")
 
 #ifndef FALSE
 #  define FALSE		0
@@ -504,12 +504,15 @@ DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks )
     pszBasename = (char *) malloc(strlen(pszFilename)+5);
     strcpy( pszBasename, pszFilename );
     for( i = (int)strlen(pszBasename)-1;
-	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
-	       && pszBasename[i] != '\\';
-	 i-- ) {}
-
-    if( pszBasename[i] == '.' )
-        pszBasename[i] = '\0';
+         i > 0 && pszBasename[i] != '/' && pszBasename[i] != '\\';
+         i-- )
+    {
+        if( pszBasename[i] == '.' )
+        {
+            pszBasename[i] = '\0';
+            break;
+        }
+    }
 
     nFullnameLen = strlen(pszBasename) + 5;
     pszFullname = (char *) malloc(nFullnameLen);
@@ -778,12 +781,15 @@ DBFCreateLL( const char * pszFilename, const char * pszCodePage, SAHooks *psHook
     pszBasename = (char *) malloc(strlen(pszFilename)+5);
     strcpy( pszBasename, pszFilename );
     for( i = (int)strlen(pszBasename)-1;
-	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
-	       && pszBasename[i] != '\\';
-	 i-- ) {}
-
-    if( pszBasename[i] == '.' )
-        pszBasename[i] = '\0';
+         i > 0 && pszBasename[i] != '/' && pszBasename[i] != '\\';
+         i-- )
+    {
+        if( pszBasename[i] == '.' )
+        {
+            pszBasename[i] = '\0';
+            break;
+        }
+    }
 
     nFullnameLen = strlen(pszBasename) + 5;
     pszFullname = (char *) malloc(nFullnameLen);
diff --git a/ogr/ogrsf_frmts/shape/shpopen.c b/ogr/ogrsf_frmts/shape/shpopen.c
index 457c3d5..860950a 100644
--- a/ogr/ogrsf_frmts/shape/shpopen.c
+++ b/ogr/ogrsf_frmts/shape/shpopen.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: shpopen.c 40020 2017-09-07 11:41:25Z rouault $
+ * $Id: shpopen.c 41847 2018-03-17 13:36:44Z rouault $
  *
  * Project:  Shapelib
  * Purpose:  Implementation of core Shapefile read/write functions.
@@ -297,7 +297,7 @@
 #include <stdio.h>
 #include <errno.h>
 
-SHP_CVSID("$Id: shpopen.c 40020 2017-09-07 11:41:25Z rouault $")
+SHP_CVSID("$Id: shpopen.c 41847 2018-03-17 13:36:44Z rouault $")
 
 typedef unsigned char uchar;
 
@@ -600,12 +600,15 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks )
     pszBasename = (char *) malloc(strlen(pszLayer)+5);
     strcpy( pszBasename, pszLayer );
     for( i = (int)strlen(pszBasename)-1;
-         i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
-             && pszBasename[i] != '\\';
-         i-- ) {}
-
-    if( pszBasename[i] == '.' )
-        pszBasename[i] = '\0';
+         i > 0 && pszBasename[i] != '/' && pszBasename[i] != '\\';
+         i-- )
+    {
+        if( pszBasename[i] == '.' )
+        {
+            pszBasename[i] = '\0';
+            break;
+        }
+    }
 
 /* -------------------------------------------------------------------- */
 /*  Open the .shp and .shx files.  Note that files pulled from  */
@@ -970,12 +973,15 @@ SHPRestoreSHX ( const char * pszLayer, const char * pszAccess, SAHooks *psHooks
     pszBasename = (char *) malloc(strlen(pszLayer)+5);
     strcpy( pszBasename, pszLayer );
     for( i = (int)strlen(pszBasename)-1;
-         i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
-             && pszBasename[i] != '\\';
-         i-- ) {}
-
-    if( pszBasename[i] == '.' )
-        pszBasename[i] = '\0';
+         i > 0 && pszBasename[i] != '/' && pszBasename[i] != '\\';
+         i-- )
+    {
+        if( pszBasename[i] == '.' )
+        {
+            pszBasename[i] = '\0';
+            break;
+        }
+    }
 
 /* -------------------------------------------------------------------- */
 /*  Open the .shp file.  Note that files pulled from                    */
@@ -2909,6 +2915,16 @@ SHPRewindObject( CPL_UNUSED SHPHandle hSHP,
         int      bInner, iVert, nVertCount, nVertStart, iCheckRing;
         double   dfSum, dfTestX, dfTestY;
 
+        nVertStart = psObject->panPartStart[iOpRing];
+
+        if( iOpRing == psObject->nParts-1 )
+            nVertCount = psObject->nVertices - psObject->panPartStart[iOpRing];
+        else
+            nVertCount = psObject->panPartStart[iOpRing+1]
+                - psObject->panPartStart[iOpRing];
+
+        if (nVertCount < 2)
+            continue;
 /* -------------------------------------------------------------------- */
 /*      Determine if this ring is an inner ring or an outer ring        */
 /*      relative to all the other rings.  For now we assume the         */
@@ -2929,25 +2945,26 @@ SHPRewindObject( CPL_UNUSED SHPHandle hSHP,
         bInner = FALSE;
         for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ )
         {
+            int nVertStartCheck, nVertCountCheck;
             int iEdge;
 
             if( iCheckRing == iOpRing )
                 continue;
 
-            nVertStart = psObject->panPartStart[iCheckRing];
+            nVertStartCheck = psObject->panPartStart[iCheckRing];
 
             if( iCheckRing == psObject->nParts-1 )
-                nVertCount = psObject->nVertices
+                nVertCountCheck = psObject->nVertices
                     - psObject->panPartStart[iCheckRing];
             else
-                nVertCount = psObject->panPartStart[iCheckRing+1]
+                nVertCountCheck = psObject->panPartStart[iCheckRing+1]
                     - psObject->panPartStart[iCheckRing];
 
-            for( iEdge = 0; iEdge < nVertCount; iEdge++ )
+            for( iEdge = 0; iEdge < nVertCountCheck; iEdge++ )
             {
                 int iNext;
 
-                if( iEdge < nVertCount-1 )
+                if( iEdge < nVertCountCheck-1 )
                     iNext = iEdge+1;
                 else
                     iNext = 0;
@@ -2956,19 +2973,19 @@ SHPRewindObject( CPL_UNUSED SHPHandle hSHP,
                  * Test whether the edge 'straddles' the horizontal ray from the test point (dfTestY,dfTestY)
                  * The rule #1 also excludes edges colinear with the ray.
                  */
-                if ( ( psObject->padfY[iEdge+nVertStart] < dfTestY
-                       && dfTestY <= psObject->padfY[iNext+nVertStart] )
-                     || ( psObject->padfY[iNext+nVertStart] < dfTestY
-                          && dfTestY <= psObject->padfY[iEdge+nVertStart] ) )
+                if ( ( psObject->padfY[iEdge+nVertStartCheck] < dfTestY
+                       && dfTestY <= psObject->padfY[iNext+nVertStartCheck] )
+                     || ( psObject->padfY[iNext+nVertStartCheck] < dfTestY
+                          && dfTestY <= psObject->padfY[iEdge+nVertStartCheck] ) )
                 {
                     /* Rule #2:
                      * Test if edge-ray intersection is on the right from the test point (dfTestY,dfTestY)
                      */
                     double const intersect =
-                        ( psObject->padfX[iEdge+nVertStart]
-                          + ( dfTestY - psObject->padfY[iEdge+nVertStart] )
-                          / ( psObject->padfY[iNext+nVertStart] - psObject->padfY[iEdge+nVertStart] )
-                          * ( psObject->padfX[iNext+nVertStart] - psObject->padfX[iEdge+nVertStart] ) );
+                        ( psObject->padfX[iEdge+nVertStartCheck]
+                          + ( dfTestY - psObject->padfY[iEdge+nVertStartCheck] )
+                          / ( psObject->padfY[iNext+nVertStartCheck] - psObject->padfY[iEdge+nVertStartCheck] )
+                          * ( psObject->padfX[iNext+nVertStartCheck] - psObject->padfX[iEdge+nVertStartCheck] ) );
 
                     if (intersect  < dfTestX)
                     {
@@ -2982,16 +2999,6 @@ SHPRewindObject( CPL_UNUSED SHPHandle hSHP,
 /*      Determine the current order of this ring so we will know if     */
 /*      it has to be reversed.                                          */
 /* -------------------------------------------------------------------- */
-        nVertStart = psObject->panPartStart[iOpRing];
-
-        if( iOpRing == psObject->nParts-1 )
-            nVertCount = psObject->nVertices - psObject->panPartStart[iOpRing];
-        else
-            nVertCount = psObject->panPartStart[iOpRing+1]
-                - psObject->panPartStart[iOpRing];
-
-        if (nVertCount < 2)
-            continue;
 
         dfSum = psObject->padfX[nVertStart] * (psObject->padfY[nVertStart+1] - psObject->padfY[nVertStart+nVertCount-1]);
         for( iVert = nVertStart + 1; iVert < nVertStart+nVertCount-1; iVert++ )
diff --git a/ogr/ogrsf_frmts/xlsx/ogrxlsxdatasource.cpp b/ogr/ogrsf_frmts/xlsx/ogrxlsxdatasource.cpp
index 7a468dd..7108b04 100644
--- a/ogr/ogrsf_frmts/xlsx/ogrxlsxdatasource.cpp
+++ b/ogr/ogrsf_frmts/xlsx/ogrxlsxdatasource.cpp
@@ -32,7 +32,7 @@
 #include "cpl_time.h"
 #include "cpl_vsi_error.h"
 
-CPL_CVSID("$Id: ogrxlsxdatasource.cpp 40632 2017-11-04 11:29:43Z rouault $");
+CPL_CVSID("$Id: ogrxlsxdatasource.cpp 41415 2018-02-05 22:42:24Z rouault $");
 
 namespace OGRXLSX {
 
@@ -1880,7 +1880,7 @@ static void WriteLayer(const char* pszName, OGRLayer* poLayer, int iLayer,
                 if (eType == OFTReal)
                 {
                     VSIFPrintfL(fp, "<c r=\"%s%d\">\n", szCol, iRow);
-                    VSIFPrintfL(fp, "<v>%.16f</v>\n", poFeature->GetFieldAsDouble(j));
+                    VSIFPrintfL(fp, "<v>%.16g</v>\n", poFeature->GetFieldAsDouble(j));
                     VSIFPrintfL(fp, "</c>\n");
                 }
                 else if (eType == OFTInteger)
@@ -1926,7 +1926,7 @@ static void WriteLayer(const char* pszName, OGRLayer* poLayer, int iLayer,
                     if (eType == OFTDate)
                         VSIFPrintfL(fp, "<v>%d</v>\n", (int)(dfNumberOfDaysSince1900 + 0.1));
                     else
-                        VSIFPrintfL(fp, "<v>%.16f</v>\n", dfNumberOfDaysSince1900);
+                        VSIFPrintfL(fp, "<v>%.16g</v>\n", dfNumberOfDaysSince1900);
                     VSIFPrintfL(fp, "</c>\n");
                 }
                 else
@@ -2091,6 +2091,12 @@ void OGRXLSXDataSource::FlushCache()
     if( !bUpdated )
         return;
 
+    /* Cause all layers to be loaded */
+    for(int i = 0; i<nLayers; i++)
+    {
+        ((OGRXLSXLayer*)papoLayers[i])->GetLayerDefn();
+    }
+
     VSIStatBufL sStat;
     if (VSIStatL(pszName, &sStat) == 0)
     {
@@ -2102,12 +2108,6 @@ void OGRXLSXDataSource::FlushCache()
         }
     }
 
-    /* Cause all layers to be initialized */
-    for(int i = 0; i<nLayers; i++)
-    {
-        ((OGRXLSXLayer*)papoLayers[i])->GetLayerDefn();
-    }
-
     /* Maintain new ZIP files opened */
     CPLString osTmpFilename(CPLSPrintf("/vsizip/%s", pszName));
     VSILFILE* fpZIP = VSIFOpenExL(osTmpFilename, "wb", true);
diff --git a/port/cpl_error.cpp b/port/cpl_error.cpp
index e614e18..c7b4bab 100644
--- a/port/cpl_error.cpp
+++ b/port/cpl_error.cpp
@@ -50,7 +50,7 @@
 #define TIMESTAMP_DEBUG
 // #define MEMORY_DEBUG
 
-CPL_CVSID("$Id: cpl_error.cpp 39443 2017-07-02 21:20:37Z rouault $");
+CPL_CVSID("$Id: cpl_error.cpp 41429 2018-02-07 10:13:35Z rouault $");
 
 static CPLMutex *hErrorMutex = NULL;
 static void *pErrorHandlerUserData = NULL;
@@ -594,10 +594,12 @@ void CPLDebug( const char * pszCategory,
 /* -------------------------------------------------------------------- */
 /*      Invoke the current error handler.                               */
 /* -------------------------------------------------------------------- */
+    bool bDebugProcessed = false;
     if( psCtx->psHandlerStack != NULL )
     {
         if( psCtx->psHandlerStack->bCatchDebug )
         {
+            bDebugProcessed = true;
             psCtx->psHandlerStack->pfnHandler( CE_Debug, CPLE_None,
                                                pszMessage );
         }
@@ -608,30 +610,28 @@ void CPLDebug( const char * pszCategory,
             {
                 if( psNode->bCatchDebug )
                 {
+                    bDebugProcessed = true;
                     psNode->pfnHandler( CE_Debug, CPLE_None, pszMessage );
                     break;
                 }
                 psNode = psNode->psNext;
             }
-            if( psNode == NULL )
-            {
-                CPLMutexHolderD( &hErrorMutex );
-                if( gbCatchDebug )
-                    pfnErrorHandler( CE_Debug, CPLE_None, pszMessage );
-                else
-                    CPLDefaultErrorHandler( CE_Debug, CPLE_None, pszMessage );
-            }
         }
     }
-    else
+
+    if( !bDebugProcessed )
     {
         CPLMutexHolderD( &hErrorMutex );
-        if( pfnErrorHandler != NULL )
+        if( gbCatchDebug )
         {
-            if( gbCatchDebug )
+            if( pfnErrorHandler != NULL )
+            {
                 pfnErrorHandler( CE_Debug, CPLE_None, pszMessage );
-            else
-                CPLDefaultErrorHandler( CE_Debug, CPLE_None, pszMessage );
+            }
+        }
+        else
+        {
+            CPLDefaultErrorHandler( CE_Debug, CPLE_None, pszMessage );
         }
     }
 
@@ -1009,10 +1009,7 @@ CPLSetErrorHandlerEx( CPLErrorHandler pfnErrorHandlerNew, void* pUserData )
 
         pfnOldHandler = pfnErrorHandler;
 
-        if( pfnErrorHandler == NULL )
-            pfnErrorHandler = CPLDefaultErrorHandler;
-        else
-            pfnErrorHandler = pfnErrorHandlerNew;
+        pfnErrorHandler = pfnErrorHandlerNew;
 
         pErrorHandlerUserData = pUserData;
     }
@@ -1173,7 +1170,7 @@ void CPL_STDCALL CPLPopErrorHandler()
  * debug messages. In some cases, this might not be desirable and the user
  * would prefer that the previous installed handler (or the default one if no
  * previous installed handler exists in the stack) deal with it. In which
- * case, this function should be called with bCatchDebug.
+ * case, this function should be called with bCatchDebug = FALSE.
  *
  * @param bCatchDebug FALSE if the current error handler should not intercept
  * debug messages
diff --git a/swig/include/Dataset.i b/swig/include/Dataset.i
index 9b4ebe7..686cc32 100644
--- a/swig/include/Dataset.i
+++ b/swig/include/Dataset.i
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: Dataset.i 37423 2017-02-19 13:25:24Z rouault $
+ * $Id: Dataset.i 41075 2017-12-19 13:58:29Z rouault $
  *
  * Name:     Dataset.i
  * Project:  GDAL Python Interface
@@ -487,8 +487,8 @@ public:
     if ( buf_type != 0 ) {
       ntype = (GDALDataType) *buf_type;
     } else {
-      int lastband = GDALGetRasterCount( self ) - 1;
-      if (lastband < 0)
+      int lastband = GDALGetRasterCount( self );
+      if (lastband <= 0)
         return CE_Failure;
       ntype = GDALGetRasterDataType( GDALGetRasterBand( self, lastband ) );
     }
@@ -549,8 +549,8 @@ CPLErr ReadRaster(  int xoff, int yoff, int xsize, int ysize,
     if ( buf_type != 0 ) {
       ntype = (GDALDataType) *buf_type;
     } else {
-      int lastband = GDALGetRasterCount( self ) - 1;
-      if (lastband < 0)
+      int lastband = GDALGetRasterCount( self );
+      if (lastband <= 0)
         return CE_Failure;
       ntype = GDALGetRasterDataType( GDALGetRasterBand( self, lastband ) );
     }
diff --git a/swig/include/perl/gdal_perl.i b/swig/include/perl/gdal_perl.i
index e2e2c87..ae4450c 100644
--- a/swig/include/perl/gdal_perl.i
+++ b/swig/include/perl/gdal_perl.i
@@ -143,8 +143,8 @@ use Geo::GDAL::Const;
 # Note that the 1/100000 digits may be used to create more than one
 # CPAN release from one GDAL release.
 
-our $VERSION = '2.0203';
-our $GDAL_VERSION = '2.2.3';
+our $VERSION = '2.0204';
+our $GDAL_VERSION = '2.2.4';
 
 =pod
 
diff --git a/swig/include/perl/ogr_perl.i b/swig/include/perl/ogr_perl.i
index 613c50d..7d496a0 100644
--- a/swig/include/perl/ogr_perl.i
+++ b/swig/include/perl/ogr_perl.i
@@ -126,7 +126,7 @@ ALTERED_DESTROY(OGRGeometryShadow, OGRc, delete_Geometry)
 %perlcode %{
 
 package Geo::OGR;
-our $VERSION = '2.0203'; # this needs to be the same as that in gdal_perl.i
+our $VERSION = '2.0204'; # this needs to be the same as that in gdal_perl.i
 
 Geo::GDAL->import(qw(:INTERNAL));
 
diff --git a/swig/include/python/gdal_python.i b/swig/include/python/gdal_python.i
index 4e92f1b..d2edff7 100644
--- a/swig/include/python/gdal_python.i
+++ b/swig/include/python/gdal_python.i
@@ -1,5 +1,5 @@
 /*
- * $Id: gdal_python.i 39126 2017-06-15 09:35:41Z rouault $
+ * $Id: gdal_python.i 41373 2018-02-01 10:09:27Z rouault $
  *
  * python specific code for gdal bindings.
  */
@@ -1179,6 +1179,8 @@ def VectorTranslateOptions(options = [], format = 'ESRI Shapefile',
          accessMode = None,
          srcSRS = None, dstSRS = None, reproject = True,
          SQLStatement = None, SQLDialect = None, where = None, selectFields = None,
+         addFields = False,
+         forceNullable = False,
          spatFilter = None, spatSRS = None,
          datasetCreationOptions = None,
          layerCreationOptions = None,
@@ -1203,6 +1205,8 @@ def VectorTranslateOptions(options = [], format = 'ESRI Shapefile',
           SQLDialect --- SQL dialect ('OGRSQL', 'SQLITE', ...)
           where --- WHERE clause to apply to source layer(s)
           selectFields --- list of fields to select
+          addFields --- whether to add new fields found in source layers (to be used with accessMode == 'append')
+          forceNullable --- whether to drop NOT NULL constraints on newly created fields
           spatFilter --- spatial filter as (minX, minY, maxX, maxY) bounding box
           spatSRS --- SRS in which the spatFilter is expressed. If not specified, it is assumed to be the one of the layer(s)
           datasetCreationOptions --- list of dataset creation options
@@ -1247,6 +1251,10 @@ def VectorTranslateOptions(options = [], format = 'ESRI Shapefile',
                 new_options += ['-overwrite']
             else:
                 raise Exception('unhandled accessMode')
+        if addFields:
+            new_options += ['-addfields']
+        if forceNullable:
+            new_options += ['-forceNullable']
         if selectFields is not None:
             val = ''
             for item in selectFields:
diff --git a/swig/perl/gdal_wrap.cpp b/swig/perl/gdal_wrap.cpp
index 0121674..6fac9d0 100644
--- a/swig/perl/gdal_wrap.cpp
+++ b/swig/perl/gdal_wrap.cpp
@@ -2718,8 +2718,8 @@ SWIGINTERN CPLErr GDALDatasetShadow_WriteRaster(GDALDatasetShadow *self,int xoff
     if ( buf_type != 0 ) {
       ntype = (GDALDataType) *buf_type;
     } else {
-      int lastband = GDALGetRasterCount( self ) - 1;
-      if (lastband < 0)
+      int lastband = GDALGetRasterCount( self );
+      if (lastband <= 0)
         return CE_Failure;
       ntype = GDALGetRasterDataType( GDALGetRasterBand( self, lastband ) );
     }
@@ -2757,8 +2757,8 @@ SWIGINTERN CPLErr GDALDatasetShadow_ReadRaster(GDALDatasetShadow *self,int xoff,
     if ( buf_type != 0 ) {
       ntype = (GDALDataType) *buf_type;
     } else {
-      int lastband = GDALGetRasterCount( self ) - 1;
-      if (lastband < 0)
+      int lastband = GDALGetRasterCount( self );
+      if (lastband <= 0)
         return CE_Failure;
       ntype = GDALGetRasterDataType( GDALGetRasterBand( self, lastband ) );
     }
diff --git a/swig/perl/lib/Geo/GDAL.pm b/swig/perl/lib/Geo/GDAL.pm
index 46a26f8..836938d 100644
--- a/swig/perl/lib/Geo/GDAL.pm
+++ b/swig/perl/lib/Geo/GDAL.pm
@@ -1056,8 +1056,8 @@ use Geo::GDAL::Const;
 # Note that the 1/100000 digits may be used to create more than one
 # CPAN release from one GDAL release.
 
-our $VERSION = '2.0203';
-our $GDAL_VERSION = '2.2.3';
+our $VERSION = '2.0204';
+our $GDAL_VERSION = '2.2.4';
 
 =pod
 
diff --git a/swig/perl/lib/Geo/OGR.pm b/swig/perl/lib/Geo/OGR.pm
index 4da05d6..d7ae6b7 100644
--- a/swig/perl/lib/Geo/OGR.pm
+++ b/swig/perl/lib/Geo/OGR.pm
@@ -960,7 +960,7 @@ package Geo::OGR;
 
 
 package Geo::OGR;
-our $VERSION = '2.0203'; # this needs to be the same as that in gdal_perl.i
+our $VERSION = '2.0204'; # this needs to be the same as that in gdal_perl.i
 
 Geo::GDAL->import(qw(:INTERNAL));
 
diff --git a/swig/python/README.txt b/swig/python/README.txt
index eeee398..6b05b03 100644
--- a/swig/python/README.txt
+++ b/swig/python/README.txt
@@ -16,7 +16,7 @@ reference documentation, but the `GDAL API Tutorial`_ includes Python examples.
 Dependencies
 ------------
  
- * libgdal (2.2.3 or greater) and header files (gdal-devel)
+ * libgdal (2.2.4 or greater) and header files (gdal-devel)
  * numpy (1.0.0 or greater) and header files (numpy-devel) (not explicitly 
    required, but many examples and utilities will not work without it)
 
diff --git a/swig/python/extensions/gdal_wrap.cpp b/swig/python/extensions/gdal_wrap.cpp
index ee022d1..0b7b0fd 100644
--- a/swig/python/extensions/gdal_wrap.cpp
+++ b/swig/python/extensions/gdal_wrap.cpp
@@ -4513,8 +4513,8 @@ SWIGINTERN CPLErr GDALDatasetShadow_WriteRaster(GDALDatasetShadow *self,int xoff
     if ( buf_type != 0 ) {
       ntype = (GDALDataType) *buf_type;
     } else {
-      int lastband = GDALGetRasterCount( self ) - 1;
-      if (lastband < 0)
+      int lastband = GDALGetRasterCount( self );
+      if (lastband <= 0)
         return CE_Failure;
       ntype = GDALGetRasterDataType( GDALGetRasterBand( self, lastband ) );
     }
diff --git a/swig/python/osgeo/gdal.py b/swig/python/osgeo/gdal.py
index 81d22b8..85b36f7 100644
--- a/swig/python/osgeo/gdal.py
+++ b/swig/python/osgeo/gdal.py
@@ -581,6 +581,8 @@ def VectorTranslateOptions(options = [], format = 'ESRI Shapefile',
          accessMode = None,
          srcSRS = None, dstSRS = None, reproject = True,
          SQLStatement = None, SQLDialect = None, where = None, selectFields = None,
+         addFields = False,
+         forceNullable = False,
          spatFilter = None, spatSRS = None,
          datasetCreationOptions = None,
          layerCreationOptions = None,
@@ -605,6 +607,8 @@ def VectorTranslateOptions(options = [], format = 'ESRI Shapefile',
           SQLDialect --- SQL dialect ('OGRSQL', 'SQLITE', ...)
           where --- WHERE clause to apply to source layer(s)
           selectFields --- list of fields to select
+          addFields --- whether to add new fields found in source layers (to be used with accessMode == 'append')
+          forceNullable --- whether to drop NOT NULL constraints on newly created fields
           spatFilter --- spatial filter as (minX, minY, maxX, maxY) bounding box
           spatSRS --- SRS in which the spatFilter is expressed. If not specified, it is assumed to be the one of the layer(s)
           datasetCreationOptions --- list of dataset creation options
@@ -649,6 +653,10 @@ def VectorTranslateOptions(options = [], format = 'ESRI Shapefile',
                 new_options += ['-overwrite']
             else:
                 raise Exception('unhandled accessMode')
+        if addFields:
+            new_options += ['-addfields']
+        if forceNullable:
+            new_options += ['-forceNullable']
         if selectFields is not None:
             val = ''
             for item in selectFields:
diff --git a/swig/python/setup.py b/swig/python/setup.py
index 6fac6f9..2b1a08f 100644
--- a/swig/python/setup.py
+++ b/swig/python/setup.py
@@ -7,7 +7,7 @@
 # Howard Butler hobu.inc at gmail.com
 
 
-gdal_version = '2.2.2'
+gdal_version = '2.2.4'
 
 import sys
 import os
@@ -26,6 +26,9 @@ from glob import glob
 if 'CXX' in os.environ and os.environ['CXX'].strip().find(' ') >= 0:
     print('WARNING: "CXX=%s" was defined in the environment and contains more than one word. Unsetting it since that is incompatible of distutils' % os.environ['CXX'])
     del os.environ['CXX']
+if 'CC' in os.environ and os.environ['CC'].strip().find(' ') >= 0:
+    print('WARNING: "CC=%s" was defined in the environment and contains more than one word. Unsetting it since that is incompatible of distutils' % os.environ['CC'])
+    del os.environ['CC']
 
 # ---------------------------------------------------------------------------
 # Switches

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/gdal.git



More information about the Pkg-grass-devel mailing list