[mapserver] 01/07: Imported Upstream version 7.0.4

Bas Couwenberg sebastic at debian.org
Mon Jan 16 18:50:34 UTC 2017


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

sebastic pushed a commit to branch master
in repository mapserver.

commit b179a46d9868121799c8640b8d0d9467860e44c3
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Mon Jan 16 18:52:06 2017 +0100

    Imported Upstream version 7.0.4
---
 CMakeLists.txt             |   2 +-
 README                     |   2 +-
 README.WIN32               | 127 ++++++++++++++++++++++++++++--------------
 mapcluster.c               |  12 +++-
 mapdrawgdal.c              |  24 +++++++-
 maplegend.c                |  67 ++++++++++++++++++++++-
 mapogcfilter.c             |   4 +-
 mapogcfiltercommon.c       |   2 +
 mapogr.cpp                 | 134 +++++++++++++++++++++++++++++++++++++--------
 mapraster.c                |  58 ++++++++++++++------
 mapresample.c              | 101 ++++++++++++++++++++++++++++++++++
 mapscript/php/README.WIN32 |  96 +++++++++++---------------------
 mapserver.h                |   1 +
 mapstring.c                |   5 +-
 mapwfs.c                   |   2 +-
 mapwfs20.c                 |  43 ++++++++++++---
 16 files changed, 514 insertions(+), 166 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0e1b8fd..3e7304e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,7 +17,7 @@ include(CheckCSourceCompiles)
 
 set (MapServer_VERSION_MAJOR 7)
 set (MapServer_VERSION_MINOR 0)
-set (MapServer_VERSION_REVISION 3)
+set (MapServer_VERSION_REVISION 4)
 set (MapServer_VERSION_SUFFIX "")
 
 set(TARGET_VERSION_MAJOR ${MapServer_VERSION_MAJOR})
diff --git a/README b/README
index b8c1926..e7bf246 100644
--- a/README
+++ b/README
@@ -67,7 +67,7 @@ License
 
 ::
 
-  Copyright (c) 2008-2016 Open Source Geospatial Foundation.
+  Copyright (c) 2008-2017 Open Source Geospatial Foundation.
   Copyright (c) 1996-2008 Regents of the University of Minnesota.
 
   Permission is hereby granted, free of charge, to any person obtaining a copy 
diff --git a/README.WIN32 b/README.WIN32
index a9c8550..d7d760f 100644
--- a/README.WIN32
+++ b/README.WIN32
@@ -22,40 +22,108 @@ IMPORTANT - READ THIS FIRST:
 
 --------------------------------------------------------------------
 
-For the developers using MSVC++, a NMAKE makefile (Makefile.vc + nmake.opt)
-to build the MapServer library and executable programs is included with
-the distribution. 
+The easyest way to build Mapserver on Windows on your own is to use the
+build-system from http://gisinternals.com/.
+GISInternals provide a complete set of sources and dependencies and even
+makefiles for the full version of Visual Studio (not Express oder Community).
+You don't have to download and compile them all by your own.
+
+If you are not using full version of Visual Studio you can not use the makefiles
+from GISInternals but you can still use the downloads to make your life easier.
+
+Building with the full version of Visual Studio is easy.
+Download the SDK for you version and follow the readme inside the packages.
+
+This Readme will cover the compilation with Visual Studio 2012 Express on
+Windows with CMake and the GISInternals-Packages for the following reasons:
+  - not everybody wants to buy Visual Studio and there is no reason to force
+    you to buy it just tu build Mapserver on Windows
+  - CMake is the configuration-system for Linux. Why should you use something
+    else which needs to be maintainerd?
+  - as of today, PHP-Mapscript is not suppored for PHP-7. PHP-5.6 is build
+    with VC11. To make PHP-Mapscript compatible with the downloadable
+    PHP-Version you need to build with VC11 wich is Visual Studio 2012.
+  - GISInternals Downloads contain most dependencies. it's way easier
+
+If you want to compile Mapserver with any other version of Visual Studio you
+can for sure use this documentation as help but maybe, some things here won't
+work for you.
 
-To build the package using the Makefile.vc and NMAKE:
+--------------------------------------------------------------------
+      Prerequisites
+--------------------------------------------------------------------
+
+To build Mapserver on Windows with Visual Studio 2012 Express you need
+Visual Studio 2012 Express installed.
+Install CMake (https://cmake.org/) and add CMake bin-directory to your PATH
+environment variable. You can even to this after opening VS2012 x86 Native
+Tools Command Prompt by entering:
+  set PATH=%PATH%;"C:\Program Files\CMake\bin"
+... if CMake is installed to "C:\Program Files\CMake" ;)
 
- - Edit nmake.opt to select (or deselect) optional components of 
-   the MapServer.  Please read the notes below about each component
-   before you move ahead with the compilation.
+--------------------------------------------------------------------
+      Downloading dependencies
+--------------------------------------------------------------------
 
- - Open a DOS prompt window
+For our first build, we will use stable releases to build mapserver.
+Download MSVC 2012 win32 Packages for GDAL-2.1.2 and Mapserver-7.0.2 from http://gisinternals.com/release.php.
+We need "Compiled binaries in a single .zip package", "GDAL and MapServer sources" and "Compiled libraries and headers".
+Download the MSVC 2012 win32 Developement Kit from http://gisinternals.com/sdk.php.
+Extract everything to C:\dev\work\release-1700-gdal-2-1-2-mapserver-7-0-2.
+There should be the directories inside now: bin, doc, gdal, include, lib, regex-0.12, relase-1700, ...
+After you got this done, feel free to use other packages which fit your needs better.
 
- - Run the VCVARS32.BAT script to initialize the VC++ environment
-   variables.  VCVARS32.BAT is automatically generated by the MSVC++
-   install procedure and should be located in the BIN sub-directory of
-   your MSVC++ installation.
+--------------------------------------------------------------------
+      Mapserver-sources
+--------------------------------------------------------------------
 
- - Then start the build with: 
-     nmake /f Makefile.vc 
+Download at least Mapserver-7.0.3 or current 7.0-Branch from github
+and extract or clone from github to C:\dev\work\mapserver.
 
-This will create "mapserv.exe" (the main MapServer CGI program), the
-other command-line utilities, "mapserver.lib" and "libmap.dll" that is 
-used by theMapScript modules.
+--------------------------------------------------------------------
+      Building Mapserver
+--------------------------------------------------------------------
 
+After downloading and extracting everything, to build Mapserver, follow this steps:
+1. Open VS2012 x86 Native Tools Command Prompt (i'm german, hope it is translated
+correctly).
+2. Add CMake-bin to your PATH:
+  set PATH=%PATH%;"C:\Program Files\CMake\bin"
+3. Create build-Directory:
+  mkdir C:\dev\work\mapserver\build
+  cd C:\dev\work\mapserver\build
+4. Configure:
+  cmake .. -G "NMake Makefiles" -DBUILD_SHARED_LIBS=1 -DCMAKE_BUILD_TYPE=Release -Wno-dev
+  cmake .. -DCMAKE_PREFIX_PATH=C:\dev\work\release-1700-gdal-2-1-2-mapserver-7-0-2;C:\dev\work\release-1700-gdal-2-1-2-mapserver-7-0-2\bin;C:\dev\work\release-1700-gdal-2-1-2-mapserver-7-0-2\lib;C:\dev\work\release-1700-gdal-2-1-2-mapserver-7-0-2\include
+  cmake .. -DREGEX_DIR=C:\dev\work\release-1700-gdal-2-1-2-mapserver-7-0-2\regex-0.12
+  cmake .. -DWITH_POSTGIS=0 -DWITH_SOS=1 -DWITH_KML=1
+  cmake .. -DWITH_CLIENT_WMS=1 -DWITH_CLIENT_WFS=1
+  cmake .. -DWITH_THREAD_SAFETY=1 -DWITH_FCGI=1
+  cmake .. -DWITH_CAIRO=1 -DCAIRO_LIBRARY=C:\dev\work\release-1700-gdal-2-1-2-mapserver-7-0-2\lib\cairo.lib
+  cmake .. -DWITH_SVGCAIRO=1 -DSVGCAIRO_LIBRARY=C:\dev\work\release-1700-gdal-2-1-2-mapserver-7-0-2\lib\libsvg-cairo.lib
+  cmake .. -DSVG_LIBRARY=1 -DSVG_LIBRARY=C:\dev\work\release-1700-gdal-2-1-2-mapserver-7-0-2\lib\libsvg.lib
+5. build
+  nmake
+
+Thats it.
+You can use all CMake parameters and options as you are used from CMake to fit mapserver to your needs from here.
+Enjoy!
 
 --------------------------------------------------------------------
       MapScript
 -------------------------------------------------------------------- 
 
 To compile the various versions of MapScript (Perl, PHP, etc) first compile
-the main mapserver directory and then see the README files in the 
-mapscript/perl, mapscript/php3 or mapscript/python directory for specific 
+the main mapserver directory and then see the README files in the
+mapscript/perl, mapscript/php or mapscript/python directory for specific
 instructions.
 
+--------------------------------------------------------------------
+      Dependencies Part 2
+--------------------------------------------------------------------
+
+The following sections descripe how to get mapserver dependencies when not
+downloading GISInternals packages.
 
 --------------------------------------------------------------------
       GD library
@@ -168,27 +236,6 @@ instructions.
    with the PNG support, make sure that the libpng that you use in mapserver 
    is the same as the one used in GDAL.
 
-------------------------------------------------------------
-        Notes on PDF suuport
-------------------------------------------------------------
-
-The PDF support allows the output of a map file as a PDF file.
-
-To be able to build mapserver with the PDF support, you need to download
-and build a PDF library from www.pdflib.com (http://www.pdflib.com/pdflib/download/index.html).
-The best option is to download the zip file containing the source code and build it. Please refer to the docs inside the zip for informations on how to build the library.  Here are some quick notes that can help in building mapserver with PDF :
-
- 1) Build the PDF lib
-
-  - open the project PDFLib.dsw
-  - build the project pdflib_dll
-  - after a sucessful build, you should have a pdflib.lib and pdblib.dll under the
-    pdflib directory
-  - copy the pdflib.dll under your system directory (ex : c:/winnt/system32)
- 
- 2) Build mapserver with PDF
-
-  - uncomment in the nmake.opt the flags related to PDF
 
 
 $Id$
diff --git a/mapcluster.c b/mapcluster.c
index 39d6a5d..daf972a 100644
--- a/mapcluster.c
+++ b/mapcluster.c
@@ -1440,7 +1440,12 @@ int msClusterLayerOpen(layerObj *layer)
     return MS_FAILURE;
 
   if (layer->layerinfo)
-    return MS_SUCCESS;  /* already open */
+  {
+    if (layer->vtable->LayerOpen != msClusterLayerOpen)
+        msLayerClose(layer);
+    else
+      return MS_SUCCESS;  /* already open */
+  }
 
   layerinfo = msClusterInitialize(layer);
 
@@ -1506,7 +1511,10 @@ int msClusterLayerTranslateFilter(layerObj *layer, expressionObj *filter, char *
     return MS_FAILURE;
   }
 
-  return layerinfo->srcLayer.vtable->LayerTranslateFilter(&layerinfo->srcLayer, filter, filteritem);
+  if (layerinfo->srcLayer.filter.type == MS_EXPRESSION && layerinfo->srcLayer.filter.tokens == NULL)
+    msTokenizeExpression(&(layerinfo->srcLayer.filter), layer->items, &(layer->numitems));
+
+  return layerinfo->srcLayer.vtable->LayerTranslateFilter(&layerinfo->srcLayer, &layerinfo->srcLayer.filter, filteritem);
 }
 
 char* msClusterLayerEscapeSQLParam(layerObj *layer, const char* pszString)
diff --git a/mapdrawgdal.c b/mapdrawgdal.c
index eb4ca15..72836c9 100644
--- a/mapdrawgdal.c
+++ b/mapdrawgdal.c
@@ -32,7 +32,7 @@
 #include "mapserver.h"
 #include "mapresample.h"
 #include "mapthread.h"
-
+#include "maptime.h"
 
 
 extern int InvGeoTransform( double *gt_in, double *gt_out );
@@ -1717,6 +1717,9 @@ msDrawRasterLayerGDAL_16BitClassification(
   unsigned char *rb_cmap[4];
   CPLErr eErr;
   rasterBufferObj *mask_rb = NULL;
+  int lastC;
+  struct mstimeval starttime, endtime;
+
   if(layer->mask) {
     int ret;
     layerObj *maskLayer = GET_LAYER(map, msGetLayerIndex(map,layer->mask));
@@ -1875,6 +1878,12 @@ msDrawRasterLayerGDAL_16BitClassification(
   rb_cmap[2] = (unsigned char *) msSmallCalloc(1,nBucketCount);
   rb_cmap[3] = (unsigned char *) msSmallCalloc(1,nBucketCount);
 
+
+  if(layer->debug >= MS_DEBUGLEVEL_TUNING) {
+    msGettimeofday(&starttime, NULL);
+  }
+
+  lastC = -1;
   for(i=0; i < nBucketCount; i++) {
     double dfOriginalValue;
 
@@ -1882,7 +1891,11 @@ msDrawRasterLayerGDAL_16BitClassification(
 
     dfOriginalValue = (i+0.5) / dfScaleRatio + dfScaleMin;
 
-    c = msGetClass_FloatRGB(layer, (float) dfOriginalValue, -1, -1, -1);
+    /* The creation of buckets takes a significant time when they are many, and many classes
+       as well. When iterating over buckets, a faster strategy is to reuse first the last used
+       class index. */
+    c = msGetClass_FloatRGB_WithFirstClassToTry(layer, (float) dfOriginalValue, -1, -1, -1, lastC);
+    lastC = c;
     if( c != -1 ) {
       int s;
 
@@ -1904,6 +1917,13 @@ msDrawRasterLayerGDAL_16BitClassification(
     }
   }
 
+  if(layer->debug >= MS_DEBUGLEVEL_TUNING) {
+    msGettimeofday(&endtime, NULL);
+    msDebug("msDrawRasterGDAL_16BitClassification() bucket creation time: %.3fs\n",
+            (endtime.tv_sec+endtime.tv_usec/1.0e6)-
+            (starttime.tv_sec+starttime.tv_usec/1.0e6) );
+  }
+
   /* ==================================================================== */
   /*      Now process the data, applying to the working imageObj.         */
   /* ==================================================================== */
diff --git a/maplegend.c b/maplegend.c
index 74dc490..b02f12c 100644
--- a/maplegend.c
+++ b/maplegend.c
@@ -35,6 +35,54 @@
 #define VMARGIN 5 /* margin at top and bottom of legend graphic */
 #define HMARGIN 5 /* margin at left and right of legend graphic */
 
+
+static int msDrawGradientSymbol(rendererVTableObj* renderer,
+                                imageObj* image_draw,
+                                double x_center,
+                                double y_center,
+                                int width,
+                                int height,
+                                styleObj* style)
+{
+    int i, j;
+    unsigned char *r,*g,*b,*a;
+    symbolObj symbol;
+    rasterBufferObj* rb;
+    symbolStyleObj symbolStyle;
+    int ret;
+
+    initSymbol(&symbol);
+    rb = (rasterBufferObj*)calloc(1,sizeof(rasterBufferObj));
+    symbol.pixmap_buffer = rb;
+    rb->type = MS_BUFFER_BYTE_RGBA;
+    rb->width = width;
+    rb->height = height;
+    rb->data.rgba.row_step = rb->width * 4;
+    rb->data.rgba.pixel_step = 4;
+    rb->data.rgba.pixels = (unsigned char*)malloc(
+                                rb->width*rb->height*4*sizeof(unsigned char));
+    b = rb->data.rgba.b = &rb->data.rgba.pixels[0];
+    g = rb->data.rgba.g = &rb->data.rgba.pixels[1];
+    r = rb->data.rgba.r = &rb->data.rgba.pixels[2];
+    a = rb->data.rgba.a = &rb->data.rgba.pixels[3];
+    for( j = 0; j < rb->height; j++ )
+    {
+        for( i = 0; i < rb->width; i++ )
+        {
+            msValueToRange(style, style->minvalue +
+                (double)i / rb->width * (style->maxvalue - style->minvalue), MS_COLORSPACE_RGB);
+            b[4*(j * rb->width + i)] = style->color.blue;
+            g[4*(j * rb->width + i)] = style->color.green;
+            r[4*(j * rb->width + i)] = style->color.red;
+            a[4*(j * rb->width + i)] = style->color.alpha;
+        }
+    }
+    INIT_SYMBOL_STYLE(symbolStyle);
+    ret = renderer->renderPixmapSymbol(image_draw, x_center, y_center, &symbol, &symbolStyle);
+    msFreeSymbol(&symbol);
+    return ret;
+}
+
 /*
  * generic function for drawing a legend icon. (added for bug #2348)
  * renderer specific drawing functions shouldn't be called directly, but through
@@ -262,8 +310,22 @@ int msDrawLegendIcon(mapObj *map, layerObj *lp, classObj *theclass,
         if (theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_NONE ||
             theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT ||
             theclass->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOLY) {
-          ret = msDrawShadeSymbol(map, image_draw, &box, theclass->styles[i], lp->scalefactor * image_draw->resolutionfactor);
-          if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
+
+            if (MS_VALID_COLOR(theclass->styles[i]->mincolor))
+            {
+                ret = msDrawGradientSymbol(renderer,
+                                           image_draw,
+                                           dstX + width / 2.,
+                                           dstY + height / 2.0,
+                                           width - 2 * polygon_contraction,
+                                           height - 2 * polygon_contraction,
+                                           theclass->styles[i]);
+            }
+            else
+            {
+                ret = msDrawShadeSymbol(map, image_draw, &box, theclass->styles[i], lp->scalefactor * image_draw->resolutionfactor);
+            }
+            if(UNLIKELY(ret == MS_FAILURE)) goto legend_icon_cleanup;
         }
         else {
           ret = msDrawTransformedShape(map, image_draw, &box,
@@ -394,7 +456,6 @@ legend_icon_cleanup:
   return ret;
 }
 
-
 imageObj *msCreateLegendIcon(mapObj* map, layerObj* lp, classObj* class, int width, int height, int scale_independant)
 {
   imageObj *image;
diff --git a/mapogcfilter.c b/mapogcfilter.c
index 0c226e1..7da559a 100644
--- a/mapogcfilter.c
+++ b/mapogcfilter.c
@@ -673,7 +673,7 @@ int FLTLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
 
     pszUseDefaultExtent = msOWSLookupMetadata(&(lp->metadata), "F",
                                               "use_default_extent_for_getfeature");
-    if( pszUseDefaultExtent && CSLTestBoolean(pszUseDefaultExtent) &&
+    if( pszUseDefaultExtent && !CSLTestBoolean(pszUseDefaultExtent) &&
         lp->connectiontype == MS_OGR )
     {
         const rectObj rectInvalid = MS_INIT_INVALID_RECT;
@@ -3004,6 +3004,8 @@ char *FLTGetIsLikeComparisonExpression(FilterEncodingNode *psFilterNode)
 
   pszValue = psFilterNode->psRightNode->pszValue;
   nLength = strlen(pszValue);
+  if( 1 + 2 * nLength + 1 + 1 >= sizeof(szTmp) )
+      return NULL;
 
   iTmp =0;
   if (nLength > 0 && pszValue[0] != pszWild[0] &&
diff --git a/mapogcfiltercommon.c b/mapogcfiltercommon.c
index 74bcb5f..600ab09 100644
--- a/mapogcfiltercommon.c
+++ b/mapogcfiltercommon.c
@@ -88,6 +88,8 @@ char *FLTGetIsLikeComparisonCommonExpression(FilterEncodingNode *psFilterNode)
 
   pszValue = psFilterNode->psRightNode->pszValue;
   nLength = strlen(pszValue);
+  if( 1 + 2 * nLength + 1 + 1 >= sizeof(szTmp) )
+      return NULL;
 
   iTmp =0;
   if (nLength > 0 && pszValue[0] != pszWild[0] && pszValue[0] != pszSingle[0] && pszValue[0] != pszEscape[0]) {
diff --git a/mapogr.cpp b/mapogr.cpp
index 07ef04b..7012f66 100644
--- a/mapogr.cpp
+++ b/mapogr.cpp
@@ -504,6 +504,9 @@ int msOGRGeometryToShape(OGRGeometryH hGeometry, shapeObj *psShape,
 
 // Special field index codes for handling text string and angle coming from
 // OGR style strings.
+
+#define MSOGR_FID_INDEX            -99
+
 #define MSOGR_LABELNUMITEMS        21
 #define MSOGR_LABELFONTNAMENAME    "OGR:LabelFont"
 #define MSOGR_LABELFONTNAMEINDEX   -100
@@ -602,6 +605,9 @@ static char **msOGRGetValues(layerObj *layer, OGRFeatureH hFeature)
     if (itemindexes[i] >= 0) {
       // Extract regular attributes
       values[i] = msStrdup(OGR_F_GetFieldAsString( hFeature, itemindexes[i]));
+    } else if (itemindexes[i] == MSOGR_FID_INDEX ) {
+      values[i] = msStrdup(CPLSPrintf(CPL_FRMT_GIB,
+                                      (GIntBig) OGR_F_GetFID(hFeature)));
     } else {
       // Handle special OGR attributes coming from StyleString
       if (!hStyleMgr) {
@@ -1283,6 +1289,16 @@ msOGRFileOpen(layerObj *layer, const char *connection )
   psInfo->last_record_index_read = -1;
   psInfo->dialect = NULL;
 
+  psInfo->pszSelect = NULL;
+  psInfo->pszSpatialFilterTableName = NULL;
+  psInfo->pszSpatialFilterGeometryColumn = NULL;
+  psInfo->pszMainTableName = NULL;
+  psInfo->pszRowId = NULL;
+  psInfo->bIsOKForSQLCompose = true;
+  psInfo->bPaging = false;
+  psInfo->bHasSpatialIndex = false;
+  psInfo->pszTablePrefix = NULL;
+
     // GDAL 1.x API
   OGRSFDriverH dr = OGR_DS_GetDriver(hDS);
   const char *name = OGR_Dr_GetName(dr);
@@ -1321,18 +1337,60 @@ msOGRFileOpen(layerObj *layer, const char *connection )
     psInfo->dialect = "PostgreSQL";
     // todo: PostgreSQL not yet tested
 
-  } // todo: other dialects, for example OGR SQL
+  } else if (strcmp(name, "GPKG") == 0 && nLayerIndex >= 0 &&
+             atoi(GDALVersionInfo("VERSION_NUM")) >= 2000000) {
+
+    bool has_rtree = false;
+    const char* test_rtree =
+        CPLSPrintf("SELECT 1 FROM sqlite_master WHERE name = 'rtree_%s_%s'",
+                   OGR_L_GetName(hLayer), OGR_L_GetGeometryColumn(hLayer));
+    OGRLayerH l = OGR_DS_ExecuteSQL(hDS, test_rtree, NULL, NULL);
+    if( l )
+    {
+        if( OGR_L_GetFeatureCount(l, TRUE) == 1 )
+        {
+            has_rtree = true;
+        }
+        OGR_DS_ReleaseResultSet(hDS, l);
+    }
+    if( has_rtree )
+    {
+        bool have_gpkg_spatialite = false;
 
+        CPLPushErrorHandler(CPLQuietErrorHandler);
 
-  psInfo->pszSelect = NULL;
-  psInfo->pszSpatialFilterTableName = NULL;
-  psInfo->pszSpatialFilterGeometryColumn = NULL;
-  psInfo->pszMainTableName = NULL;
-  psInfo->pszRowId = NULL;
-  psInfo->bIsOKForSQLCompose = true;
-  psInfo->bPaging = false;
-  psInfo->bHasSpatialIndex = false;
-  psInfo->pszTablePrefix = NULL;
+        // test for Spatialite >= 4.3 support in driver
+        const char *test_spatialite = "SELECT spatialite_version()";
+        l = OGR_DS_ExecuteSQL(hDS, test_spatialite, NULL, NULL);
+        if (l) {
+            OGRFeatureH hFeat = OGR_L_GetNextFeature(l);
+            if( hFeat )
+            {
+                const char* pszVersion = OGR_F_GetFieldAsString(hFeat, 0);
+                have_gpkg_spatialite = atof(pszVersion) >= 4.3;
+                OGR_F_Destroy(hFeat);
+            }
+            OGR_DS_ReleaseResultSet(hDS, l);
+        }
+        CPLPopErrorHandler();
+
+        if( have_gpkg_spatialite )
+        {
+            psInfo->pszMainTableName = msStrdup( OGR_L_GetName(hLayer) );
+            psInfo->pszSpatialFilterTableName = msStrdup( OGR_L_GetName(hLayer) );
+            psInfo->pszSpatialFilterGeometryColumn = msStrdup( OGR_L_GetGeometryColumn(hLayer) );
+            psInfo->dialect = "GPKG";
+            psInfo->bPaging = true;
+            psInfo->bHasSpatialIndex = true;
+        }
+        else
+            msDebug("msOGRFileOpen: Spatialite support in GPKG not enabled\n");
+    }
+    else
+    {
+        msDebug("msOGRFileOpen: RTree index not available\n");
+    }
+  }
 
   if( psInfo->dialect != NULL && EQUAL(psInfo->dialect, "Spatialite") )
     msOGRFileOpenSpatialite(layer, pszLayerDef, psInfo);
@@ -1806,7 +1864,7 @@ char *msOGRGetToken(layerObj* layer, tokenListNodeObjPtr *node) {
         char wild_any =  '%';
         char wild_one = '_';
 
-        if (EQUAL(info->dialect, "Spatialite")) {
+        if (EQUAL(info->dialect, "Spatialite") || EQUAL(info->dialect, "GPKG")) {
             if (case_sensitive) {
                 op = "GLOB";
                 wild_any = '*';
@@ -1926,7 +1984,7 @@ char *msOGRGetToken(layerObj* layer, tokenListNodeObjPtr *node) {
         else
         {
             const char *SQLtype = "float(16)";
-            if (EQUAL(info->dialect, "Spatialite"))
+            if (EQUAL(info->dialect, "Spatialite") || EQUAL(info->dialect, "GPKG"))
                 SQLtype = "REAL";
             else if (EQUAL(info->dialect, "PostgreSQL"))
                 SQLtype = "double precision";
@@ -2205,17 +2263,19 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
         }
         psInfo->rect = rect;
 
-        bool bSpatialiteAddOrderByFID = false;
+        bool bSpatialiteOrGPKGAddOrderByFID = false;
 
-        if( psInfo->dialect && EQUAL(psInfo->dialect, "Spatialite") &&
-            psInfo->pszMainTableName != NULL && psInfo->bHasSpatialIndex &&
+        if( psInfo->dialect && psInfo->pszMainTableName != NULL && 
+            ( (EQUAL(psInfo->dialect, "Spatialite") && psInfo->bHasSpatialIndex)
+              || EQUAL(psInfo->dialect, "GPKG") ) &&
             bIsValidRect )
         {
             select = msStringConcatenate(select, " JOIN ");
 
             char szSpatialIndexName[256];
             snprintf( szSpatialIndexName, sizeof(szSpatialIndexName),
-                        "idx_%s_%s",
+                        "%s_%s_%s",
+                        EQUAL(psInfo->dialect, "Spatialite") ? "idx" : "rtree",
                         psInfo->pszSpatialFilterTableName,
                         psInfo->pszSpatialFilterGeometryColumn );
             char* pszEscapedSpatialIndexName = msLayerEscapePropertyName(
@@ -2240,20 +2300,35 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
             }
             else
                 select = msStringConcatenate(select, "ROWID");
-            select = msStringConcatenate(select, " = ms_spat_idx.pkid AND ");
+            if( EQUAL(psInfo->dialect, "Spatialite") )
+                select = msStringConcatenate(select, " = ms_spat_idx.pkid AND ");
+            else
+                select = msStringConcatenate(select, " = ms_spat_idx.id AND ");
 
             char szCond[256];
-            snprintf(szCond, sizeof(szCond),
+            if( EQUAL(psInfo->dialect, "Spatialite") )
+            {
+                snprintf(szCond, sizeof(szCond),
                         "ms_spat_idx.xmin <= %.15g AND ms_spat_idx.xmax >= %.15g AND "
                         "ms_spat_idx.ymin <= %.15g AND ms_spat_idx.ymax >= %.15g",
                         rect.maxx, rect.minx, rect.maxy, rect.miny);
+            }
+            else
+            {
+                snprintf(szCond, sizeof(szCond),
+                        "ms_spat_idx.minx <= %.15g AND ms_spat_idx.maxx >= %.15g AND "
+                        "ms_spat_idx.miny <= %.15g AND ms_spat_idx.maxy >= %.15g",
+                        rect.maxx, rect.minx, rect.maxy, rect.miny);
+            }
             select = msStringConcatenate(select, szCond);
 
-            bSpatialiteAddOrderByFID = true;
+            bSpatialiteOrGPKGAddOrderByFID = true;
         }
 
         if (psInfo->dialect) {
-            if (EQUAL(psInfo->dialect, "Spatialite") || EQUAL(psInfo->dialect, "PostgreSQL")) {
+            if (EQUAL(psInfo->dialect, "Spatialite") ||
+                EQUAL(psInfo->dialect, "GPKG") ||
+                EQUAL(psInfo->dialect, "PostgreSQL")) {
                 const char *sql = layer->filter.native_string;
                 if (sql && *sql != '\0') {
                     if (filter) filter = msStringConcatenate(filter, "AND ");
@@ -2318,7 +2393,7 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
             }
         }
 
-        if( bSpatialiteAddOrderByFID )
+        if( bSpatialiteOrGPKGAddOrderByFID )
         {
             if( sort == NULL )
                 sort = msStringConcatenate(NULL, " ORDER BY ");
@@ -2429,13 +2504,15 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
                 OGR_L_SetSpatialFilter( psInfo->hLayer, hSpatialFilterPolygon );
                 OGR_G_DestroyGeometry( hSpatialFilterPolygon );
             }
+
+            if (layer->debug >= MS_DEBUGLEVEL_VVV)
+            {
+                msDebug("msOGRFileWhichShapes: Setting spatial filter to %.15g %.15g %.15g %.15g\n", rect.minx, rect.miny, rect.maxx, rect.maxy );
+            }
         }
 
         psInfo->rect = rect;
 
-        if (layer->debug >= MS_DEBUGLEVEL_VVV)
-            msDebug("msOGRFileWhichShapes: Setting spatial filter to %.15g %.15g %.15g %.15g\n", rect.minx, rect.miny, rect.maxx, rect.maxy );
-
         /* ------------------------------------------------------------------
          * Apply an attribute filter if we have one prefixed with a WHERE
          * keyword in the filter string.  Otherwise, ensure the attribute
@@ -3575,7 +3652,16 @@ static int msOGRLayerInitItemInfo(layerObj *layer)
         itemindexes[i] = MSOGR_SYMBOLPARAMINDEX 
                           + atoi(layer->items[i] + MSOGR_SYMBOLPARAMNAMELEN);
     else
+    {
       itemindexes[i] = OGR_FD_GetFieldIndex( hDefn, layer->items[i] );
+      if( itemindexes[i] == -1 )
+      {
+          if( EQUAL( layer->items[i], OGR_L_GetFIDColumn( psInfo->hLayer ) ) )
+          {
+              itemindexes[i] = MSOGR_FID_INDEX;
+          }
+      }
+    }
     if(itemindexes[i] == -1) {
       msSetError(MS_OGRERR,
                  "Invalid Field name: %s",
diff --git a/mapraster.c b/mapraster.c
index e8ac0f9..1fd5bea 100644
--- a/mapraster.c
+++ b/mapraster.c
@@ -60,7 +60,7 @@ extern parseResultObj yypresult; /* result of parsing, true/false */
 /*                         msGetClass_String()                          */
 /************************************************************************/
 
-static int msGetClass_String( layerObj *layer, colorObj *color, const char *pixel_value )
+static int msGetClass_String( layerObj *layer, colorObj *color, const char *pixel_value, int firstClassToTry )
 
 {
   int i;
@@ -80,9 +80,18 @@ static int msGetClass_String( layerObj *layer, colorObj *color, const char *pixe
   /*      Setup values list for expressions.                              */
   /* -------------------------------------------------------------------- */
   numitems = 4;
-  sprintf( red_value, "%d", color->red );
-  sprintf( green_value, "%d", color->green );
-  sprintf( blue_value, "%d", color->blue );
+  if( color->red == -1 && color->green == -1 && color->blue == -1 )
+  {
+    strcpy(red_value, "-1");
+    strcpy(green_value, "-1");
+    strcpy(blue_value, "-1");
+  }
+  else
+  {
+    sprintf( red_value, "%d", color->red );
+    sprintf( green_value, "%d", color->green );
+    sprintf( blue_value, "%d", color->blue );
+  }
 
   item_values[0] = (char *)pixel_value;
   item_values[1] = red_value;
@@ -92,18 +101,24 @@ static int msGetClass_String( layerObj *layer, colorObj *color, const char *pixe
   /* -------------------------------------------------------------------- */
   /*      Loop over classes till we find a match.                         */
   /* -------------------------------------------------------------------- */
-  for(i=0; i<layer->numclasses; i++) {
+  for(i= (firstClassToTry < 0 ) ? 0 : -1; i<layer->numclasses; i++) {
+
+    int idx = i;
+    if( i < 0 )
+        idx = firstClassToTry;
+    else if( i == firstClassToTry )
+        continue;
 
     /* check for correct classgroup, if set */
-    if ( layer->class[i]->group && layer->classgroup &&
-         strcasecmp(layer->class[i]->group, layer->classgroup) != 0 )
+    if ( layer->class[idx]->group && layer->classgroup &&
+         strcasecmp(layer->class[idx]->group, layer->classgroup) != 0 )
       continue;
 
     /* Empty expression - always matches */
-    if (layer->class[i]->expression.string == NULL)
+    if (layer->class[idx]->expression.string == NULL)
       return(i);
 
-    switch(layer->class[i]->expression.type) {
+    switch(layer->class[idx]->expression.type) {
 
         /* -------------------------------------------------------------------- */
         /*      Simple string match                                             */
@@ -114,22 +129,22 @@ static int msGetClass_String( layerObj *layer, colorObj *color, const char *pixe
         while( *tmpstr1 == ' ' )
           tmpstr1++;
 
-        if(strcmp(layer->class[i]->expression.string, tmpstr1) == 0) return(i); /* matched */
+        if(strcmp(layer->class[idx]->expression.string, tmpstr1) == 0) return(idx); /* matched */
         break;
 
         /* -------------------------------------------------------------------- */
         /*      Regular expression.  Rarely used for raster.                    */
         /* -------------------------------------------------------------------- */
       case(MS_REGEX):
-        if(!layer->class[i]->expression.compiled) {
-          if(ms_regcomp(&(layer->class[i]->expression.regex), layer->class[i]->expression.string, MS_REG_EXTENDED|MS_REG_NOSUB) != 0) { /* compile the expression  */
+        if(!layer->class[idx]->expression.compiled) {
+          if(ms_regcomp(&(layer->class[idx]->expression.regex), layer->class[idx]->expression.string, MS_REG_EXTENDED|MS_REG_NOSUB) != 0) { /* compile the expression  */
             msSetError(MS_REGEXERR, "Invalid regular expression.", "msGetClass()");
             return(-1);
           }
-          layer->class[i]->expression.compiled = MS_TRUE;
+          layer->class[idx]->expression.compiled = MS_TRUE;
         }
 
-        if(ms_regexec(&(layer->class[i]->expression.regex), pixel_value, 0, NULL, 0) == 0) return(i); /* got a match */
+        if(ms_regexec(&(layer->class[idx]->expression.regex), pixel_value, 0, NULL, 0) == 0) return(idx); /* got a match */
         break;
 
         /* -------------------------------------------------------------------- */
@@ -139,7 +154,7 @@ static int msGetClass_String( layerObj *layer, colorObj *color, const char *pixe
         int status;
         parseObj p;
         shapeObj dummy_shape;
-        expressionObj *expression = &(layer->class[i]->expression);
+        expressionObj *expression = &(layer->class[idx]->expression);
 
         dummy_shape.numvalues = numitems;
         dummy_shape.values = item_values;
@@ -160,7 +175,7 @@ static int msGetClass_String( layerObj *layer, colorObj *color, const char *pixe
         }
 
         if( p.result.intval )
-          return i;
+          return idx;
         break;
       }
     }
@@ -179,7 +194,7 @@ int msGetClass(layerObj *layer, colorObj *color, int colormap_index)
 
   snprintf( pixel_value, sizeof(pixel_value), "%d", colormap_index );
 
-  return msGetClass_String( layer, color, pixel_value );
+  return msGetClass_String( layer, color, pixel_value, -1 );
 }
 
 /************************************************************************/
@@ -191,6 +206,13 @@ int msGetClass(layerObj *layer, colorObj *color, int colormap_index)
 
 int msGetClass_FloatRGB(layerObj *layer, float fValue, int red, int green, int blue )
 {
+    return msGetClass_FloatRGB_WithFirstClassToTry(
+                layer, fValue, red, green, blue, -1);
+}
+
+
+int msGetClass_FloatRGB_WithFirstClassToTry(layerObj *layer, float fValue, int red, int green, int blue, int firstClassToTry )
+{
   char pixel_value[100];
   colorObj color;
 
@@ -200,7 +222,7 @@ int msGetClass_FloatRGB(layerObj *layer, float fValue, int red, int green, int b
 
   snprintf( pixel_value, sizeof(pixel_value), "%18g", fValue );
 
-  return msGetClass_String( layer, &color, pixel_value );
+  return msGetClass_String( layer, &color, pixel_value, firstClassToTry );
 }
 
 #if defined(USE_GDAL)
diff --git a/mapresample.c b/mapresample.c
index 7107bcb..c1a98b2 100644
--- a/mapresample.c
+++ b/mapresample.c
@@ -1123,6 +1123,107 @@ static int msTransformMapToSource( int nDstXSize, int nDstYSize,
     }
   }
 
+  /* -------------------------------------------------------------------- */
+  /*      Deal with discontinuities related to lon_wrap=XXX in source     */
+  /*      projection. In that case we must check if the points at         */
+  /*      lon_wrap +/- 180deg are in the output raster.                   */
+  /* -------------------------------------------------------------------- */
+  if( bOutInit && pj_is_latlong(psSrcProj->proj) )
+  {
+      int bHasLonWrap = MS_FALSE;
+      double dfLonWrap = 0;
+      for( i = 0; i < psSrcProj->numargs; i++ )
+      {
+          if( strncmp(psSrcProj->args[i], "lon_wrap=",
+                      strlen("lon_wrap=")) == 0 )
+          {
+              bHasLonWrap = MS_TRUE;
+              dfLonWrap = atof( psSrcProj->args[i] + strlen("lon_wrap=") );
+              break;
+          }
+      }
+
+      if( bHasLonWrap )
+      {
+          double x2[2], y2[2], z2[2];
+          int nCountY = 0;
+          double dfY = 0.0;
+          double dfXMinOut = 0.0;
+          double dfYMinOut = 0.0;
+          double dfXMaxOut = 0.0;
+          double dfYMaxOut = 0.0;
+
+          /* Find out average y coordinate in src projection */
+          for( i = 0; i < nSamples; i++ ) {
+              if( y[i] != HUGE_VAL ) {
+                  dfY += y[i];
+                  nCountY ++;
+              }
+          }
+          dfY /= nCountY;
+
+          /* Compute bounds of output raster */
+          for( i = 0; i < 4; i ++ )
+          {
+              double dfX = adfDstGeoTransform[0] +
+                ((i == 1 || i == 2) ? nDstXSize : 0) * adfDstGeoTransform[1] +
+                ((i == 1 || i == 3 ) ? nDstYSize : 0) * adfDstGeoTransform[2];
+              double dfY = adfDstGeoTransform[3] +
+                ((i == 1 || i == 2) ? nDstXSize : 0) * adfDstGeoTransform[4] +
+                ((i == 1 || i == 3 ) ? nDstYSize : 0) * adfDstGeoTransform[5];
+              if( i == 0 || dfX < dfXMinOut ) dfXMinOut = dfX;
+              if( i == 0 || dfY < dfYMinOut ) dfYMinOut = dfY;
+              if( i == 0 || dfX > dfXMaxOut ) dfXMaxOut = dfX;
+              if( i == 0 || dfY > dfYMaxOut ) dfYMaxOut = dfY;
+          }
+
+          x2[0] = dfLonWrap-180+1e-7;
+          y2[0] = dfY;
+          z2[0] = 0.0;
+
+          x2[1] = dfLonWrap+180-1e-7;
+          y2[1] = dfY;
+          z2[1] = 0.0;
+
+          msAcquireLock( TLOCK_PROJ );
+          pj_transform( psSrcProj->proj, psDstProj->proj,
+                        2, 1, x2, y2, z2 );
+          msReleaseLock( TLOCK_PROJ );
+
+          if( x2[0] >= dfXMinOut && x2[0] <= dfXMaxOut &&
+              y2[0] >= dfYMinOut && y2[0] <= dfYMaxOut )
+          {
+                double x_out =      adfInvSrcGeoTransform[0]
+                            +   (dfLonWrap-180)*adfInvSrcGeoTransform[1]
+                            +   dfY*adfInvSrcGeoTransform[2];
+                double y_out =      adfInvSrcGeoTransform[3]
+                            +   (dfLonWrap-180)*adfInvSrcGeoTransform[4]
+                            +   dfY*adfInvSrcGeoTransform[5];
+
+                psSrcExtent->minx = MS_MIN(psSrcExtent->minx, x_out);
+                psSrcExtent->maxx = MS_MAX(psSrcExtent->maxx, x_out);
+                psSrcExtent->miny = MS_MIN(psSrcExtent->miny, y_out);
+                psSrcExtent->maxy = MS_MAX(psSrcExtent->maxy, y_out);
+          }
+
+          if( x2[1] >= dfXMinOut && x2[1] <= dfXMaxOut &&
+              x2[1] >= dfYMinOut && y2[1] <= dfYMaxOut )
+          {
+                double x_out =      adfInvSrcGeoTransform[0]
+                            +   (dfLonWrap+180)*adfInvSrcGeoTransform[1]
+                            +   dfY*adfInvSrcGeoTransform[2];
+                double y_out =      adfInvSrcGeoTransform[3]
+                            +   (dfLonWrap+180)*adfInvSrcGeoTransform[4]
+                            +   dfY*adfInvSrcGeoTransform[5];
+
+                psSrcExtent->minx = MS_MIN(psSrcExtent->minx, x_out);
+                psSrcExtent->maxx = MS_MAX(psSrcExtent->maxx, x_out);
+                psSrcExtent->miny = MS_MIN(psSrcExtent->miny, y_out);
+                psSrcExtent->maxy = MS_MAX(psSrcExtent->maxy, y_out);
+          }
+      }
+  }
+
   if( !bOutInit )
     return MS_FALSE;
 
diff --git a/mapscript/php/README.WIN32 b/mapscript/php/README.WIN32
index 3744193..9da7451 100644
--- a/mapscript/php/README.WIN32
+++ b/mapscript/php/README.WIN32
@@ -1,95 +1,63 @@
                     PHP/MapScript Mapserver Module
                     ==============================
 
---------------------------------------------------------------------
-IMPORTANT - READ THIS FIRST:
-
-  The Win32 build process is not very friendly for unexperienced users.
-  So it is strongly recommended that you use one of the precompiled 
-  versions of php_mapscript.dll available on DM Solutions Group's web site:
-     http://www2.dmsolutions.ca/mapserver/dl/
-
-  If for some reason you still decide to compile Win32 binaries yourself,
-  then don't do it unless you really know what you're doing... and
-  hopefully the rest of this file contains some hints that may help 
-  you.  Good Luck!
---------------------------------------------------------------------
-
-This file contains informations specific to building the PHP/MapScript
-extension on Windows using MSVC++ 6.0.  
+This README covers building PHP-Mapscript on Windows with Visual Studio 2012 Express for PHP-5.6 x86 Thread-Safe.
 
-See also the file README for more general information about the 
-PHP/MapScript extension.
+If you already built Mapserver with instructions from ../../README.WIN32, you are only a few steps away from PHP-Mapscript.
+If not, first build Mapserver as descriped in ../../README.WIN32.
 
-                      --------------------------
 
-Step 1: Build the PHP.LIB import library
-=======
-
- *** PHP3 ***
- Before you can build the 'php3_mapscript.dll' extension, you need the 
- PHP.LIB import library.  To build PHP.LIB, you will have to download the 
- php_3.0.14.tar.gz source code, and follow the instructions in the
- README.WIN32 file in there to build php.exe with MSVC++ 6.0.
-
-  - Extract php_3.0.14.tar.gz to your HD
-  - Read the php_3.0.14\README.WIN32 file.
-  - Open php_3.0.14\win32\php3.dsw using MSVC++ 6.0
-  - Start building php.exe, this will also create PHP.LIB
-
- *** PHP4.0.4 (and more recent versions) ***
- The PHP 4.0.4 win32 binaries (php-4.0.4-Win32.zip) distributed on 
- http://www.php.net/ include the necessary php4ts.lib import library,
- so it is not necessary to build the PHP4 source in this case:
-  - Extract php-4.0.4.tar.gz  (this will create a php-4.0.4 source tree)
-  - Extract php-4.0.4-Win32.zip and configure PHP4 on your server as per
-    the instructions in the file install.txt included in the zip file.
-  - mkdir php-4.0.4\lib (i.e. 'mkdir lib' in the root of the source tree)
-  - Copy php4ts.lib (from php-4.0.4-Win32.zip) to php-4.0.4\lib
-  - Continue with the rest of the instructions below.
+--------------------------------------------------------------------
+Step 1: Build PHP
+--------------------------------------------------------------------
 
-Step 2: Build PHP3_MAPSCRIPT.DLL/PHP_MAPSCRIPT.DLL
-=======
+Build PHP-5.6 x86 Thread-Safe with Visual Studio 2012 Express as descriped here: https://wiki.php.net/internals/windows/stepbystepbuild
+Extract the PHP-SDK to C:\dev\work\php-sdk to be able to use the commands, used here.
 
-Review the mapscript\php3\makefile.vc and make any modifications required
-for your configuration.  Make sure PHP_SOURCE_DIR points to where you 
-installed the PHP source tree in step 1 above.
+PHP sources and compiled binaries should be in C:\dev\work\php-sdk\phpdev\vc11\x86\php-5.6.28-src now.
 
-Then to compile PHP3_MAPSCRIPT.DLL/PHP_MAPSCRIPT.DLL:
 
- - Open a DOS prompt window
- - Run the VCVARS32.BAT script to initialize the VC++ environment
-   variables.  VCVARS32.BAT is automatically generated by the MSVC++
-   install procedure and should be located in the BIN sub-directory of
-   your MSVC++ installation.
- - Then start the build with: 
-     nmake /f makefile.vc 
+--------------------------------------------------------------------
+Step 2: Build PHP-Mapscript
+--------------------------------------------------------------------
 
-This will create the "PHP3_MAPSCRIPT.DLL" for PHP3, or "PHP_MAPSCRIPT.DLL"
-for PHP4.
+After step 5 of ../../README.WIN32 you have an open VS2012 x86 Native Tools Shell in build-Directory in your Mapserver sources (C:\dev\work\mapserver\build).
+If not, open VS2012 x86 Native Tools Shell, add cmake to your PATH (see ../../README.WIN32) and "cd C:\dev\work\mapserver\build".
+1. Tell CMake to build Mapscript by entering:
+  cmake .. -DWITH_PHP=1 -DPHP5_EXTENSION_DIR=C:\dev\builds\php-5.6.28-Win32-VC11-x86_mapscript\ext -DPHP5_INCLUDES=C:\dev\work\php-sdk\phpdev\vc11\x86\php-5.6.28-src
+2. build:
+  nmake
 
 
+--------------------------------------------------------------------
 Step 3: Install PHP3_MAPSCRIPT.DLL/PHP_MAPSCRIPT.DLL
-=======
+--------------------------------------------------------------------
 
-PHP3_MAPSCRIPT.DLL is a regular PHP module, you should copy it to the same
-directory as the other PHP3_*.DLL modules that came with PHP.  
+PHP_MAPSCRIPT.DLL is a regular PHP module, you should copy it to the same
+directory as the other PHP_*.DLL modules that came with PHP.
 
 Then the module can be loaded in one of 2 ways:
 
- - Adding a "extension=php3_mapscript.dll" line to the PHP3.INI file will
+ - Adding a "extension=php_mapscript.dll" line to the PHP3.INI file will
    load it automatically for every PHP page.
 
  - The other possibility is to load the module only when needed using the
    following PHP call:
-        dl("php3_mapscript.dll");  // for the PHP3 module
-     or
         dl("php_mapscript.dll");  // for the PHP4 module
 
 You can test that the module is properly loaded by executing the
 phpinfo() command in a PHP page... the "MapScript" extension should be
 included in the list of extensions in the phpinfo() report.
 
+--------------------------------------------------------------------
+Maybe Step 4: Troubleshooting
+--------------------------------------------------------------------
+
+If you have any problems, getting PHP-MapScript running, add it to php.ini and try to start php from command line. It may tell you, what is missing.
+PHP-MapScript has the same dependencies as Mapserver itself so you may need to add paths to the dependencies and libmap.dll/mapserver.dll to you systems PATH environment variable.
+If this all does not help, use tools like SysInternals Process Monitor (https://technet.microsoft.com/de-de/sysinternals/processmonitor.aspx) or Dependency Walker (http://www.dependencywalker.com/) to find, what is missing.
+Open php_mapscript.dll with Dependency Walker to see missing dependencies.
+
 
 --------------------------
 $Id$
diff --git a/mapserver.h b/mapserver.h
index 905dec9..32182fa 100644
--- a/mapserver.h
+++ b/mapserver.h
@@ -2589,6 +2589,7 @@ void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char
   MS_DLL_EXPORT int msGetClass(layerObj *layer, colorObj *color, int colormap_index);
   MS_DLL_EXPORT int msGetClass_FloatRGB(layerObj *layer, float fValue,
                                         int red, int green, int blue );
+  int msGetClass_FloatRGB_WithFirstClassToTry(layerObj *layer, float fValue, int red, int green, int blue, int firstClassToTry );
 
   /* in mapdrawgdal.c */
   MS_DLL_EXPORT int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image, rasterBufferObj *rb, void *hDSVoid );
diff --git a/mapstring.c b/mapstring.c
index 122f4cd..24d8c31 100644
--- a/mapstring.c
+++ b/mapstring.c
@@ -728,8 +728,9 @@ char *msBuildPath(char *pszReturnPath, const char *abs_path, const char *path)
     abslen = strlen(abs_path);
 
   if((pathlen + abslen + 2) > MS_MAXPATHLEN) {
-    msSetError(MS_IOERR, "(%s%s): path is too long", "msBuildPath()",
-               abs_path, path);
+    msSetError(MS_IOERR, "Path is too long.  Check server logs.",
+               "msBuildPath()");
+    msDebug("msBuildPath(): (%s%s): path is too long.\n", abs_path, path);
     return NULL;
   }
 
diff --git a/mapwfs.c b/mapwfs.c
index bac3f21..4051788 100644
--- a/mapwfs.c
+++ b/mapwfs.c
@@ -2153,7 +2153,7 @@ static int msWFSRunBasicGetFeature(mapObj* map,
 
     pszUseDefaultExtent = msOWSLookupMetadata(&(lp->metadata), "F",
                                               "use_default_extent_for_getfeature");
-    if( pszUseDefaultExtent && CSLTestBoolean(pszUseDefaultExtent) &&
+    if( pszUseDefaultExtent && !CSLTestBoolean(pszUseDefaultExtent) &&
         lp->connectiontype == MS_OGR )
     {
         const rectObj rectInvalid = MS_INIT_INVALID_RECT;
diff --git a/mapwfs20.c b/mapwfs20.c
index b4402ec..50da844 100644
--- a/mapwfs20.c
+++ b/mapwfs20.c
@@ -824,15 +824,44 @@ static char* msWFSGetStoredQuery(mapObj *map, const char* pszURN)
         FILE* f = fopen(value, "rb");
         if( f != NULL )
         {
-            char* pszBuffer = (char*) msSmallMalloc(32000);
-            int nread = fread(pszBuffer, 1, 32000-1, f);
-            fclose(f);
-            if( nread > 0 )
+            char* pszBuffer;
+            int nread;
+            long length;
+
+            fseek(f, 0, SEEK_END);
+            length = ftell(f);
+            if( length > 1000000 )
+            {
+                msSetError(MS_WFSERR, "%s: too big (%ld bytes > 1000000)",
+                           "msWFSGetStoredQuery()", value, length);
+                fclose(f);
+            }
+            else
             {
-                pszBuffer[nread-1] = '\0';
-                return pszBuffer;
+                fseek(f, 0, SEEK_SET);
+                pszBuffer = (char*) malloc((int)length + 1);
+                if( pszBuffer == NULL )
+                {
+                    msSetError(MS_WFSERR, "Cannot allocate %d bytes to read %s",
+                               "msWFSGetStoredQuery()",
+                               (int)length + 1, value);
+                    fclose(f);
+                }
+                else
+                {
+                    nread = (int)fread(pszBuffer, 1, length, f);
+                    fclose(f);
+                    if( nread == length )
+                    {
+                        pszBuffer[nread] = '\0';
+                        return pszBuffer;
+                    }
+                    msSetError(MS_WFSERR, "Could only read %d bytes / %d of %s",
+                               "msWFSGetStoredQuery()",
+                               nread, (int)length, value);
+                    msFree(pszBuffer);
+                }
             }
-            msFree(pszBuffer);
         }
         else
         {

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



More information about the Pkg-grass-devel mailing list