[Git][debian-gis-team/mapserver][upstream] New upstream version 8.6.1
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Mon Mar 23 17:34:54 GMT 2026
Bas Couwenberg pushed to branch upstream at Debian GIS Project / mapserver
Commits:
209dc6af by Bas Couwenberg at 2026-03-23T18:14:09+01:00
New upstream version 8.6.1
- - - - -
23 changed files:
- CITATION.cff
- CMakeLists.txt
- HISTORY.md
- LICENSE.md
- ci/ubuntu/build.sh
- src/idw.c
- src/mapcontour.c
- src/mapcopy.c
- src/mapdraw.c
- src/mapdrawgdal.c
- src/mapogcsld.cpp
- src/mapogr.cpp
- src/mappostgis.cpp
- src/mapproject.c
- src/mapproject.h
- src/mapquery.cpp
- src/maprendering.c
- src/mapserver.h
- src/mapstring.cpp
- src/mapuvraster.cpp
- src/mapwcs.cpp
- src/mapwcs20.cpp
- src/mapwms.cpp
Changes:
=====================================
CITATION.cff
=====================================
@@ -1,8 +1,8 @@
cff-version: 1.2.0
title: MapServer
message: If you use this software, please cite it using the metadata from this file.
-version: 8.6.0
-date-released: 2025-12-03
+version: 8.6.1
+date-released: 2026-03-23
abstract: MapServer is an Open Source platform for publishing spatial data and interactive mapping applications to the web.
type: software
authors:
=====================================
CMakeLists.txt
=====================================
@@ -17,7 +17,7 @@ include(CheckCSourceCompiles)
set (MapServer_VERSION_MAJOR 8)
set (MapServer_VERSION_MINOR 6)
-set (MapServer_VERSION_REVISION 0)
+set (MapServer_VERSION_REVISION 1)
set (MapServer_VERSION_SUFFIX "")
# Set C++ version
@@ -1049,6 +1049,9 @@ set(USE_GENERIC_MS_NINT 1)
add_definitions(-D_XKEYCHECK_H=1)
endif(WIN32)
+# Defines M_PI in particular
+add_definitions(-D_USE_MATH_DEFINES)
+
#INSTALL(FILES mapserver-api.h ${PROJECT_BINARY_DIR}/mapserver-version.h DESTINATION include)
if(USE_ORACLE_PLUGIN)
=====================================
HISTORY.md
=====================================
@@ -13,6 +13,15 @@ https://mapserver.org/development/changelog/
The online Migration Guide can be found at https://mapserver.org/MIGRATION_GUIDE.html
+8.6.1 release (2026-03-23)
+--------------------------
+
+- security: fix potential heap buffer overflow (#7461)
+
+- No longer depend on GDAL's cpl_port.h MIN/MAX/ABS macros (#7438)
+
+see detailed changelog for other fixes
+
8.6.0 release (2025-12-03)
--------------------------
=====================================
LICENSE.md
=====================================
@@ -4,7 +4,7 @@ MapServer Licensing
MapServer General
-----------------
-Copyright (c) 2008-2025 Open Source Geospatial Foundation.
+Copyright (c) 2008-2026 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
=====================================
ci/ubuntu/build.sh
=====================================
@@ -47,10 +47,10 @@ python -m http.server &> /dev/null &
echo "PHP version"
php -v
PHPVersionMinor=$(php --version | head -n 1 | cut -d " " -f 2 | cut -c 1,3)
-if [ ${PHPVersionMinor} -gt 82 ]; then
- cd php && curl -LO https://phar.phpunit.de/phpunit-12.phar
+if [ ${PHPVersionMinor} -gt 83 ]; then
+ cd php && curl -LO https://phar.phpunit.de/phpunit-13.phar
echo "PHPUnit version"
- php phpunit-12.phar --version
+ php phpunit-13.phar --version
else
cd php && curl -LO https://phar.phpunit.de/phpunit-10.phar
echo "PHPUnit version"
=====================================
src/idw.c
=====================================
@@ -69,7 +69,7 @@ void msIdwProcessing(layerObj *layer,
if (interpParamsProcessing) {
interpParams->radius = atof(interpParamsProcessing);
} else {
- interpParams->radius = MAX(layer->map->width, layer->map->height);
+ interpParams->radius = MS_MAX(layer->map->width, layer->map->height);
}
interpParamsProcessing =
=====================================
src/mapcontour.c
=====================================
@@ -59,6 +59,10 @@ typedef struct {
OGRDataSourceH hOGRDS;
double cellsize;
+ /* set if the map->extent and map->projection are
+ valid in msContourLayerWhichShapes() */
+ mapObj *mapToUseForWhichShapes;
+
} contourLayerInfo;
static int msContourLayerInitItemInfo(layerObj *layer) {
@@ -226,12 +230,7 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) {
src_xsize = GDALGetRasterXSize(clinfo->hOrigDS);
src_ysize = GDALGetRasterYSize(clinfo->hOrigDS);
- /* set the Dataset extent */
msGetGDALGeoTransform(clinfo->hOrigDS, map, layer, adfGeoTransform);
- clinfo->extent.minx = adfGeoTransform[0];
- clinfo->extent.maxy = adfGeoTransform[3];
- clinfo->extent.maxx = adfGeoTransform[0] + src_xsize * adfGeoTransform[1];
- clinfo->extent.miny = adfGeoTransform[3] + src_ysize * adfGeoTransform[5];
if (layer->transform) {
if (layer->debug)
@@ -240,12 +239,41 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) {
InvGeoTransform(adfGeoTransform, adfInvGeoTransform);
mapRect = rect;
- if (map->cellsize == 0) {
- map->cellsize = msAdjustExtent(&mapRect, map->width, map->height);
- }
- map_cellsize_x = map_cellsize_y = map->cellsize;
+
/* if necessary, project the searchrect to source coords */
if (msProjectionsDiffer(&(map->projection), &(layer->projection))) {
+
+ /* Deal with request in WebMercator, overlapping the anti-meridian,
+ * and raster in geographic coordinates within (approximatively)
+ * [-180,180] longitude range.
+ */
+ double map_cellsize_x_override = 0;
+ if (clinfo->mapToUseForWhichShapes) {
+ mapRect = clinfo->mapToUseForWhichShapes->extent;
+ const double WEB_MERCATOR_MAX_X = 20037508.34;
+ if (clinfo->mapToUseForWhichShapes->projection.numargs == 1 &&
+ strcmp(clinfo->mapToUseForWhichShapes->projection.args[0],
+ "init=epsg:3857") == 0 &&
+ (clinfo->mapToUseForWhichShapes->extent.minx <
+ -WEB_MERCATOR_MAX_X ||
+ clinfo->mapToUseForWhichShapes->extent.maxx >
+ WEB_MERCATOR_MAX_X) &&
+ msProjIsGeographicCRS(&layer->projection) &&
+ clinfo->extent.minx > -180 - 2 * adfGeoTransform[1] &&
+ clinfo->extent.maxx < 180 + 2 * adfGeoTransform[1]) {
+
+ // First do a reprojection with +over to compute cellsize_x
+ msProjectRect(&map->projection, &layer->projection, &mapRect);
+ map_cellsize_x_override =
+ MS_CELLSIZE(mapRect.minx, mapRect.maxx, map->width);
+
+ // Then clamp to +/- 180 deg
+ mapRect = clinfo->mapToUseForWhichShapes->extent;
+ mapRect.minx = MS_MAX(mapRect.minx, -WEB_MERCATOR_MAX_X);
+ mapRect.maxx = MS_MIN(mapRect.maxx, WEB_MERCATOR_MAX_X);
+ }
+ }
+
if (msProjectRect(&map->projection, &layer->projection, &mapRect) !=
MS_SUCCESS) {
msDebug("msContourLayerReadRaster(%s): unable to reproject map request "
@@ -254,7 +282,10 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) {
return MS_FAILURE;
}
- map_cellsize_x = MS_CELLSIZE(mapRect.minx, mapRect.maxx, map->width);
+ map_cellsize_x =
+ map_cellsize_x_override != 0
+ ? map_cellsize_x_override
+ : MS_CELLSIZE(mapRect.minx, mapRect.maxx, map->width);
map_cellsize_y = MS_CELLSIZE(mapRect.miny, mapRect.maxy, map->height);
/* if the projection failed to project the extent requested, we need to
@@ -279,6 +310,11 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) {
map_cellsize_y = MS_CONVERT_UNIT(
src_unit, dst_unit, MS_CELLSIZE(rect.miny, rect.maxy, map->height));
}
+ } else {
+ if (map->cellsize == 0) {
+ map->cellsize = msAdjustExtent(&mapRect, map->width, map->height);
+ }
+ map_cellsize_x = map_cellsize_y = map->cellsize;
}
if (map_cellsize_x == 0 || map_cellsize_y == 0) {
@@ -309,19 +345,21 @@ static int msContourLayerReadRaster(layerObj *layer, rectObj rect) {
* there is no point in interpolating the data for contours in this case.
*/
- virtual_grid_step_x = (int)floor(map_cellsize_x / ABS(adfGeoTransform[1]));
+ virtual_grid_step_x =
+ (int)floor(map_cellsize_x / MS_ABS(adfGeoTransform[1]));
if (virtual_grid_step_x < 1)
virtual_grid_step_x =
1; /* Do not interpolate data if grid sampling step < 1 */
- virtual_grid_step_y = (int)floor(map_cellsize_y / ABS(adfGeoTransform[5]));
+ virtual_grid_step_y =
+ (int)floor(map_cellsize_y / MS_ABS(adfGeoTransform[5]));
if (virtual_grid_step_y < 1)
virtual_grid_step_y =
1; /* Do not interpolate data if grid sampling step < 1 */
/* target cellsize is a multiple of raw data cellsize based on grid step*/
- dst_cellsize_x = ABS(adfGeoTransform[1]) * virtual_grid_step_x;
- dst_cellsize_y = ABS(adfGeoTransform[5]) * virtual_grid_step_y;
+ dst_cellsize_x = MS_ABS(adfGeoTransform[1]) * virtual_grid_step_x;
+ dst_cellsize_y = MS_ABS(adfGeoTransform[5]) * virtual_grid_step_y;
/* Compute overlap between source and target views */
@@ -750,6 +788,19 @@ int msContourLayerOpen(layerObj *layer) {
} else
clinfo->hOrigDS = NULL;
+ if (clinfo->hOrigDS) {
+ const int src_xsize = GDALGetRasterXSize(clinfo->hOrigDS);
+ const int src_ysize = GDALGetRasterYSize(clinfo->hOrigDS);
+
+ /* set the Dataset extent */
+ double adfGeoTransform[6];
+ msGetGDALGeoTransform(clinfo->hOrigDS, layer->map, layer, adfGeoTransform);
+ clinfo->extent.minx = adfGeoTransform[0];
+ clinfo->extent.maxy = adfGeoTransform[3];
+ clinfo->extent.maxx = adfGeoTransform[0] + src_xsize * adfGeoTransform[1];
+ clinfo->extent.miny = adfGeoTransform[3] + src_ysize * adfGeoTransform[5];
+ }
+
msReleaseLock(TLOCK_GDAL);
if (clinfo->hOrigDS == NULL) {
@@ -758,24 +809,6 @@ int msContourLayerOpen(layerObj *layer) {
return MS_FAILURE;
}
- /* Open the raster source */
- if (msContourLayerReadRaster(layer, layer->map->extent) != MS_SUCCESS)
- return MS_FAILURE;
-
- /* Generate Contour Dataset */
- if (msContourLayerGenerateContour(layer) != MS_SUCCESS)
- return MS_FAILURE;
-
- if (clinfo->hDS) {
- GDALClose(clinfo->hDS);
- clinfo->hDS = NULL;
- free(clinfo->buffer);
- }
-
- /* Open our virtual ogr layer */
- if (clinfo->hOGRDS && (msLayerOpen(&clinfo->ogrLayer) != MS_SUCCESS))
- return MS_FAILURE;
-
return MS_SUCCESS;
}
@@ -833,7 +866,13 @@ int msContourLayerGetItems(layerObj *layer) {
layer->items[layer->numitems++] = msStrdup(elevItem);
}
- return msLayerGetItems(&clinfo->ogrLayer);
+ return MS_SUCCESS;
+}
+
+void msContourLayerUseMapExtentAndProjectionForNextWhichShapes(layerObj *layer,
+ mapObj *map) {
+ contourLayerInfo *clinfo = (contourLayerInfo *)layer->layerinfo;
+ clinfo->mapToUseForWhichShapes = map;
}
int msContourLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) {
@@ -900,7 +939,8 @@ int msContourLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) {
clinfo->ogrLayer.items[i] = msStrdup(layer->items[i]);
}
- return msLayerWhichShapes(&clinfo->ogrLayer, rect, isQuery);
+ const rectObj invalid_rect = MS_INIT_INVALID_RECT;
+ return msLayerWhichShapes(&clinfo->ogrLayer, invalid_rect, isQuery);
}
int msContourLayerGetShape(layerObj *layer, shapeObj *shape,
=====================================
src/mapcopy.c
=====================================
@@ -56,7 +56,7 @@
**********************************************************************/
int msCopyProjectionExtended(projectionObj *dst, const projectionObj *src,
- char **args, int num_args) {
+ const char *const *args, int num_args) {
MS_COPYSTELEM(numargs);
MS_COPYSTELEM(gt);
=====================================
src/mapdraw.c
=====================================
@@ -1163,6 +1163,8 @@ int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image) {
searchrect = msUVRASTERGetSearchRect(layer, map);
bDone = MS_TRUE;
+ } else if (layer->connectiontype == MS_CONTOUR) {
+ msContourLayerUseMapExtentAndProjectionForNextWhichShapes(layer, map);
}
if (!bDone)
@@ -1183,6 +1185,8 @@ int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image) {
msUVRASTERLayerUseMapExtentAndProjectionForNextWhichShapes(layer, NULL);
} else if (layer->connectiontype == MS_RASTER_LABEL) {
msRasterLabelLayerUseMapExtentAndProjectionForNextWhichShapes(layer, NULL);
+ } else if (layer->connectiontype == MS_CONTOUR) {
+ msContourLayerUseMapExtentAndProjectionForNextWhichShapes(layer, NULL);
}
if (status == MS_DONE) { /* no overlap */
=====================================
src/mapdrawgdal.c
=====================================
@@ -601,7 +601,7 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image,
const int j =
bScaleColors
- ? MAX(0, MIN(255, (int)((i - dfScaleMin) * dfScaleRatio)))
+ ? MS_MAX(0, MS_MIN(255, (int)((i - dfScaleMin) * dfScaleRatio)))
: i;
pixel.red = sEntry.c1;
@@ -685,7 +685,7 @@ int msDrawRasterLayerGDAL(mapObj *map, layerObj *layer, imageObj *image,
GDALGetColorEntryAsRGB(hColorMap, i, &sEntry);
const int j =
bScaleColors
- ? MAX(0, MIN(255, (int)((i - dfScaleMin) * dfScaleRatio)))
+ ? MS_MAX(0, MS_MIN(255, (int)((i - dfScaleMin) * dfScaleRatio)))
: i;
if (sEntry.c4 != 0 &&
@@ -1497,7 +1497,7 @@ static int LoadGDALImages(GDALDatasetH hDS, int band_numbers[4], int band_count,
pabyBuffer = pabyWholeBuffer + iColorIndex * nPixelCount;
if (iColorIndex == 0 && bGotNoData)
- *ppbIsNoDataBuffer = (bool *)calloc(nPixelCount, 1);
+ *ppbIsNoDataBuffer = (bool *)calloc(nPixelCount, sizeof(bool));
for (i = 0; i < nPixelCount; i++) {
float fScaledValue;
=====================================
src/mapogcsld.cpp
=====================================
@@ -2894,7 +2894,7 @@ int msSLDParseRasterSymbolizer(CPLXMLNode *psRoot, layerObj *psLayer,
} else if (strcasecmp(psNode->pszValue, "Threshold") == 0) {
papszThresholds[nThresholds] = psNode->psChild->pszValue;
nThresholds++;
- if (nValues == nMaxThreshold) {
+ if (nThresholds == nMaxThreshold) {
nMaxThreshold += 100;
papszThresholds = (char **)msSmallRealloc(
papszThresholds, sizeof(char *) * nMaxThreshold);
=====================================
src/mapogr.cpp
=====================================
@@ -33,6 +33,8 @@
#include "mapproject.h"
#include "mapthread.h"
#include "mapows.h"
+
+#include <algorithm>
#include <string>
#include <vector>
@@ -2223,10 +2225,10 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect,
* no _efficient_ way to do that with OGR.
* ------------------------------------------------------------------ */
if (psInfo->rect_is_defined) {
- rect.minx = MAX(psInfo->rect.minx, rect.minx);
- rect.miny = MAX(psInfo->rect.miny, rect.miny);
- rect.maxx = MIN(psInfo->rect.maxx, rect.maxx);
- rect.maxy = MIN(psInfo->rect.maxy, rect.maxy);
+ rect.minx = std::max(psInfo->rect.minx, rect.minx);
+ rect.miny = std::max(psInfo->rect.miny, rect.miny);
+ rect.maxx = std::min(psInfo->rect.maxx, rect.maxx);
+ rect.maxy = std::min(psInfo->rect.maxy, rect.maxy);
bIsValidRect = true;
}
psInfo->rect = rect;
=====================================
src/mappostgis.cpp
=====================================
@@ -54,9 +54,6 @@
**
*/
-/* required for MSVC */
-#define _USE_MATH_DEFINES
-
#include <assert.h>
#include <string.h>
#include <math.h>
=====================================
src/mapproject.c
=====================================
@@ -1056,7 +1056,11 @@ msProjectGetLineCuttingCase(reprojectionObj *reprojector) {
}
}
- if (!(!in->gt.need_geotransform && !msProjIsGeographicCRS(in) &&
+ const bool isRotatedPole =
+ msProjIsGeographicCRS(in) && in->proj &&
+ proj_crs_is_derived(in->proj_ctx->proj_ctx, in->proj);
+ if (!(!in->gt.need_geotransform &&
+ (!msProjIsGeographicCRS(in) || isRotatedPole) &&
(msProjIsGeographicCRS(out) ||
(out->numargs == 1 && strcmp(out->args[0], "init=epsg:3857") == 0)))) {
reprojector->lineCuttingCase = LINE_CUTTING_NONE;
@@ -1065,6 +1069,7 @@ msProjectGetLineCuttingCase(reprojectionObj *reprojector) {
int srcIsPolar;
double extremeLongEasting;
+ double extremeLatNorthing;
if (msProjIsGeographicCRS(out)) {
pointObj p;
double gt3 = out->gt.need_geotransform ? out->gt.geotransform[3] : 0.0;
@@ -1075,6 +1080,7 @@ msProjectGetLineCuttingCase(reprojectionObj *reprojector) {
srcIsPolar = msProjectPointEx(reprojector, &p) == MS_SUCCESS &&
fabs(gt3 + p.x * gt4 + p.y * gt5 - 90) < 1e-8;
extremeLongEasting = 180;
+ extremeLatNorthing = 90;
} else {
pointObj p1;
pointObj p2;
@@ -1087,44 +1093,143 @@ msProjectGetLineCuttingCase(reprojectionObj *reprojector) {
msProjectPointEx(reprojector, &p2) == MS_SUCCESS &&
fabs((p1.x - p2.x) * gt1) > 20e6;
extremeLongEasting = 20037508.3427892;
+ extremeLatNorthing = extremeLongEasting;
}
- if (!srcIsPolar) {
+ if (!srcIsPolar && !isRotatedPole) {
reprojector->lineCuttingCase = LINE_CUTTING_NONE;
return reprojector->lineCuttingCase;
}
pointObj p = {0}; // initialize
- double invgt0 = out->gt.need_geotransform ? out->gt.invgeotransform[0] : 0.0;
- double invgt1 = out->gt.need_geotransform ? out->gt.invgeotransform[1] : 1.0;
- double invgt3 = out->gt.need_geotransform ? out->gt.invgeotransform[3] : 0.0;
- double invgt4 = out->gt.need_geotransform ? out->gt.invgeotransform[4] : 0.0;
+ const double invgt0 =
+ out->gt.need_geotransform ? out->gt.invgeotransform[0] : 0.0;
+ const double invgt1 =
+ out->gt.need_geotransform ? out->gt.invgeotransform[1] : 1.0;
+ const double invgt3 =
+ out->gt.need_geotransform ? out->gt.invgeotransform[3] : 0.0;
+ const double invgt4 =
+ out->gt.need_geotransform ? out->gt.invgeotransform[4] : 0.0;
+ const double invgt5 =
+ out->gt.need_geotransform ? out->gt.invgeotransform[5] : 1.0;
lineObj newLine = {0, NULL};
- p.x = invgt0 + -extremeLongEasting * (1 - EPS) * invgt1;
- p.y = invgt3 + -extremeLongEasting * (1 - EPS) * invgt4;
- /* coverity[swapped_arguments] */
- msProjectPoint(out, in, &p);
- pointObj first = p;
- msAddPointToLine(&newLine, &p);
+ if (isRotatedPole) {
+ // Thresholds determined experimentally...
+ const double EPSILON = 1e-5;
+ if (msProjIsGeographicCRS(out)) {
+ const int stepCountMiddleLat = 400;
+ const int stepCountHighLat = 100;
+ const double middleLat = 80;
+ const double poleLat = 90;
+
+ for (int j = 0; j <= stepCountHighLat; j++) {
+ p.x = invgt0 + extremeLongEasting * (1 - EPSILON) * invgt1;
+ p.y =
+ invgt3 +
+ (-poleLat + (poleLat - middleLat) * j / stepCountHighLat) * invgt5;
+ /* coverity[swapped_arguments] */
+ msProjectPoint(out, in, &p);
+ msAddPointToLine(&newLine, &p);
+ }
+
+ for (int j = 0; j <= stepCountMiddleLat; j++) {
+ p.x = invgt0 + extremeLongEasting * (1 - EPSILON) * invgt1;
+ p.y = invgt3 +
+ (-middleLat + (2 * middleLat) * j / stepCountMiddleLat) * invgt5;
+ /* coverity[swapped_arguments] */
+ msProjectPoint(out, in, &p);
+ msAddPointToLine(&newLine, &p);
+ }
+
+ for (int j = 0; j <= stepCountHighLat; ++j) {
+ p.x = invgt0 + extremeLongEasting * (1 - EPSILON) * invgt1;
+ p.y =
+ invgt3 +
+ (middleLat + (poleLat - middleLat) * j / stepCountHighLat) * invgt5;
+ /* coverity[swapped_arguments] */
+ msProjectPoint(out, in, &p);
+ msAddPointToLine(&newLine, &p);
+ }
+
+ for (int j = stepCountHighLat; j >= 0; --j) {
+ p.x = invgt0 - extremeLongEasting * (1 - EPSILON) * invgt1;
+ p.y =
+ invgt3 +
+ (middleLat + (poleLat - middleLat) * j / stepCountHighLat) * invgt5;
+ /* coverity[swapped_arguments] */
+ msProjectPoint(out, in, &p);
+ msAddPointToLine(&newLine, &p);
+ }
+
+ for (int j = stepCountMiddleLat; j >= 0; --j) {
+ p.x = invgt0 - extremeLongEasting * (1 - EPSILON) * invgt1;
+ p.y = invgt3 +
+ (-middleLat + (2 * middleLat) * j / stepCountMiddleLat) * invgt5;
+ /* coverity[swapped_arguments] */
+ msProjectPoint(out, in, &p);
+ msAddPointToLine(&newLine, &p);
+ }
- p.x = invgt0 + extremeLongEasting * (1 - EPS) * invgt1;
- p.y = invgt3 + extremeLongEasting * (1 - EPS) * invgt4;
- /* coverity[swapped_arguments] */
- msProjectPoint(out, in, &p);
- msAddPointToLine(&newLine, &p);
+ for (int j = stepCountHighLat; j >= 0; --j) {
+ p.x = invgt0 - extremeLongEasting * (1 - EPSILON) * invgt1;
+ p.y =
+ invgt3 +
+ (-poleLat + (poleLat - middleLat) * j / stepCountHighLat) * invgt5;
+ /* coverity[swapped_arguments] */
+ msProjectPoint(out, in, &p);
+ msAddPointToLine(&newLine, &p);
+ }
+ } else {
+ const int stepCountHalf = 200;
+ for (int j = 0; j <= 2 * stepCountHalf; j++) {
+ p.x = invgt0 + extremeLongEasting * (1 - EPSILON) * invgt1;
+ p.y = invgt3 +
+ (-extremeLatNorthing + extremeLatNorthing * j / stepCountHalf) *
+ invgt5;
+ /* coverity[swapped_arguments] */
+ msProjectPoint(out, in, &p);
+ msAddPointToLine(&newLine, &p);
+ }
+
+ for (int j = 2 * stepCountHalf; j >= 0; j--) {
+ p.x = invgt0 - extremeLongEasting * (1 - EPSILON) * invgt1;
+ p.y = invgt3 +
+ (-extremeLatNorthing + extremeLatNorthing * j / stepCountHalf) *
+ invgt5;
+ /* coverity[swapped_arguments] */
+ msProjectPoint(out, in, &p);
+ msAddPointToLine(&newLine, &p);
+ }
+ }
+
+ pointObj firstPoint = newLine.point[0];
+ msAddPointToLine(&newLine, &firstPoint);
+ } else {
+ p.x = invgt0 + -extremeLongEasting * (1 - EPS) * invgt1;
+ p.y = invgt3 + -extremeLongEasting * (1 - EPS) * invgt4;
+ /* coverity[swapped_arguments] */
+ msProjectPoint(out, in, &p);
+ pointObj first = p;
+ msAddPointToLine(&newLine, &p);
- p.x = 0;
- p.y = 0;
- msAddPointToLine(&newLine, &p);
+ p.x = invgt0 + extremeLongEasting * (1 - EPS) * invgt1;
+ p.y = invgt3 + extremeLongEasting * (1 - EPS) * invgt4;
+ msProjectPoint(out, in, &p);
+ msAddPointToLine(&newLine, &p);
- msAddPointToLine(&newLine, &first);
+ p.x = 0;
+ p.y = 0;
+ msAddPointToLine(&newLine, &p);
+
+ msAddPointToLine(&newLine, &first);
+ }
msInitShape(&(reprojector->splitShape));
reprojector->splitShape.type = MS_SHAPE_POLYGON;
msAddLineDirectly(&(reprojector->splitShape), &newLine);
- reprojector->lineCuttingCase = LINE_CUTTING_FROM_POLAR;
+ reprojector->lineCuttingCase = LINE_CUTTING_WITH_SHAPE;
return reprojector->lineCuttingCase;
}
#endif
@@ -1219,7 +1324,7 @@ static int msProjectShapeLine(reprojectionObj *reprojector, shapeObj *shape,
int use_splitShape = MS_FALSE;
int use_splitShape_check_intersects = MS_FALSE;
if (shape->type == MS_SHAPE_LINE &&
- msProjectGetLineCuttingCase(reprojector) == LINE_CUTTING_FROM_POLAR) {
+ msProjectGetLineCuttingCase(reprojector) == LINE_CUTTING_WITH_SHAPE) {
use_splitShape = MS_TRUE;
use_splitShape_check_intersects = MS_TRUE;
} else if (shape->type == MS_SHAPE_LINE &&
@@ -1864,7 +1969,7 @@ int msProjectHasLonWrap(projectionObj *in, double *pdfLonWrap) {
/************************************************************************/
int msProjectRect(projectionObj *in, projectionObj *out, rectObj *rect) {
- char *over = "+over";
+ const char *over = "+over";
int ret;
int bFreeInOver = MS_FALSE;
int bFreeOutOver = MS_FALSE;
=====================================
src/mapproject.h
=====================================
@@ -49,7 +49,7 @@ typedef struct projectionContext projectionContext;
typedef enum {
LINE_CUTTING_UNKNOWN = -1,
LINE_CUTTING_NONE = 0,
- LINE_CUTTING_FROM_POLAR = 1,
+ LINE_CUTTING_WITH_SHAPE = 1,
LINE_CUTTING_FROM_LONGLAT_WRAP0 = 2
} msLineCuttingCase;
#endif
=====================================
src/mapquery.cpp
=====================================
@@ -1981,6 +1981,8 @@ int msQueryByPoint(mapObj *map) {
int classindex = -1;
styleObj *style = nullptr;
imageObj *cachedImage = nullptr;
+ double center_x_in_map = 0;
+ double center_y_in_map = 0;
SearchSymbol(mapObj *map) : m_map(map) {}
~SearchSymbol() {
@@ -2014,6 +2016,8 @@ int msQueryByPoint(mapObj *map) {
classindex = other.classindex;
std::swap(style, other.style);
std::swap(cachedImage, other.cachedImage);
+ center_x_in_map = other.center_x_in_map;
+ center_y_in_map = other.center_y_in_map;
}
SearchSymbol &operator=(SearchSymbol &&other) {
m_map = other.m_map;
@@ -2021,6 +2025,8 @@ int msQueryByPoint(mapObj *map) {
classindex = other.classindex;
std::swap(style, other.style);
std::swap(cachedImage, other.cachedImage);
+ center_x_in_map = other.center_x_in_map;
+ center_y_in_map = other.center_y_in_map;
return *this;
}
};
@@ -2066,16 +2072,21 @@ int msQueryByPoint(mapObj *map) {
computeSymbolStyle(&s, style, symbol, style->scalefactor,
resolutionfactor);
+ double pos_offset_x = 0;
+ double pos_offset_y = 0;
+ if (msAdjustMarkerPos(map, style, symbol, &pos_offset_x,
+ &pos_offset_y, style->scalefactor,
+ s.rotation) != MS_SUCCESS) {
+ continue;
+ }
+
double center_x =
MS_MAP2IMAGE_X(map->query.point.x, map->extent.minx, cellx);
double center_y =
MS_MAP2IMAGE_Y(map->query.point.y, map->extent.maxy, celly);
- if (msAdjustMarkerPos(map, style, symbol, ¢er_x, ¢er_y,
- style->scalefactor,
- s.rotation) != MS_SUCCESS) {
- continue;
- }
+ center_x -= pos_offset_x;
+ center_y -= pos_offset_y;
center_x = MS_IMAGE2MAP_X(center_x, map->extent.minx, cellx);
center_y = MS_IMAGE2MAP_Y(center_y, map->extent.maxy, celly);
@@ -2116,6 +2127,8 @@ int msQueryByPoint(mapObj *map) {
SearchSymbol searchSymbol(map);
searchSymbol.style = style;
searchSymbol.classindex = classindex;
+ searchSymbol.center_x_in_map = center_x;
+ searchSymbol.center_y_in_map = center_y;
lineObj line = {0, NULL};
line.numpoints = 5;
@@ -2135,14 +2148,18 @@ int msQueryByPoint(mapObj *map) {
searchSymbols.push_back(std::move(searchSymbol));
- rect.minx = MIN(rect.minx,
- center_x + MIN(MIN(P1_X, P2_X), MIN(P3_X, P4_X)));
- rect.miny = MIN(rect.miny,
- center_y + MIN(MIN(P1_Y, P2_Y), MIN(P3_Y, P4_Y)));
- rect.maxx = MAX(rect.maxx,
- center_x + MAX(MAX(P1_X, P2_X), MAX(P3_X, P4_X)));
- rect.maxy = MAX(rect.maxy,
- center_y + MAX(MAX(P1_Y, P2_Y), MAX(P3_Y, P4_Y)));
+ rect.minx =
+ std::min(rect.minx, center_x + std::min(std::min(P1_X, P2_X),
+ std::min(P3_X, P4_X)));
+ rect.miny =
+ std::min(rect.miny, center_y + std::min(std::min(P1_Y, P2_Y),
+ std::min(P3_Y, P4_Y)));
+ rect.maxx =
+ std::max(rect.maxx, center_x + std::max(std::max(P1_X, P2_X),
+ std::max(P3_X, P4_X)));
+ rect.maxy =
+ std::max(rect.maxy, center_y + std::max(std::max(P1_Y, P2_Y),
+ std::max(P3_Y, P4_Y)));
}
}
};
@@ -2327,10 +2344,10 @@ int msQueryByPoint(mapObj *map) {
pointObj imCenter;
imCenter.x = searchSymbol.cachedImage->width / 2;
imCenter.y = searchSymbol.cachedImage->height / 2;
- if (msDrawMarkerSymbol(map, searchSymbol.cachedImage, &imCenter,
- searchSymbol.style,
- searchSymbol.style->scalefactor) !=
- MS_SUCCESS) {
+ if (msDrawMarkerSymbolInternal(
+ map, searchSymbol.cachedImage, &imCenter,
+ searchSymbol.style, searchSymbol.style->scalefactor,
+ /* adjustMarkerPos = */ false) != MS_SUCCESS) {
msSetError(MS_MISCERR, "Unable to draw symbol image.",
"msQueryByPoint()");
return (MS_FAILURE);
@@ -2347,10 +2364,12 @@ int msQueryByPoint(mapObj *map) {
const int test_x = static_cast<int>(std::round(
searchSymbol.cachedImage->width / 2 +
- (map->query.point.x - shape.line[0].point[0].x) / cellx));
+ (searchSymbol.center_x_in_map - shape.line[0].point[0].x) /
+ cellx));
const int test_y = static_cast<int>(std::round(
searchSymbol.cachedImage->height / 2 -
- (map->query.point.y - shape.line[0].point[0].y) / celly));
+ (searchSymbol.center_y_in_map - shape.line[0].point[0].y) /
+ celly));
// Check that the queried pixel hits a non-transparent pixel of
// the symbol
=====================================
src/maprendering.c
=====================================
@@ -899,6 +899,13 @@ int msDrawShadeSymbol(mapObj *map, imageObj *image, shapeObj *p,
int msDrawMarkerSymbol(mapObj *map, imageObj *image, pointObj *p,
styleObj *style, double scalefactor) {
+ return msDrawMarkerSymbolInternal(map, image, p, style, scalefactor,
+ /* adjustMarkerPos =*/true);
+}
+
+int msDrawMarkerSymbolInternal(mapObj *map, imageObj *image, pointObj *p,
+ styleObj *style, double scalefactor,
+ bool adjustMarkerPos) {
int ret = MS_SUCCESS;
if (!p)
return MS_SUCCESS;
@@ -937,7 +944,8 @@ int msDrawMarkerSymbol(mapObj *map, imageObj *image, pointObj *p,
p_x = p->x;
p_y = p->y;
- if (MS_UNLIKELY(MS_FAILURE == msAdjustMarkerPos(map, style, symbol, &p_x,
+ if (adjustMarkerPos &&
+ MS_UNLIKELY(MS_FAILURE == msAdjustMarkerPos(map, style, symbol, &p_x,
&p_y, scalefactor,
s.rotation))) {
return MS_FAILURE;
=====================================
src/mapserver.h
=====================================
@@ -73,6 +73,12 @@
#define MS_UNLIKELY(x) (x)
#endif
+/** Macro to compute the minimum of 2 values */
+#define MS_MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+/** Macro to compute the maximum of 2 values */
+#define MS_MAX(a, b) (((a) > (b)) ? (a) : (b))
+
/* definition of ms_int32/ms_uint32 */
#include <limits.h>
#ifndef _WIN32
@@ -3303,6 +3309,9 @@ void msRasterLabelLayerUseMapExtentAndProjectionForNextWhichShapes(
layerObj *layer, mapObj *map);
rectObj msRasterLabelGetSearchRect(layerObj *layer, mapObj *map);
+void msContourLayerUseMapExtentAndProjectionForNextWhichShapes(layerObj *layer,
+ mapObj *map);
+
/* ==================================================================== */
/* Prototypes for functions in mapdraw.c */
/* ==================================================================== */
@@ -3351,6 +3360,12 @@ MS_DLL_EXPORT int msValueToRange(styleObj *style, double fieldVal,
MS_DLL_EXPORT int WARN_UNUSED msDrawMarkerSymbol(mapObj *map, imageObj *image,
pointObj *p, styleObj *style,
double scalefactor);
+
+int WARN_UNUSED msDrawMarkerSymbolInternal(mapObj *map, imageObj *image,
+ pointObj *p, styleObj *style,
+ double scalefactor,
+ bool adjustMarkerPos);
+
MS_DLL_EXPORT int WARN_UNUSED msDrawLineSymbol(mapObj *map, imageObj *image,
shapeObj *p, styleObj *style,
double scalefactor);
@@ -3718,7 +3733,8 @@ MS_DLL_EXPORT int msCopyProjection(projectionObj *dst,
const projectionObj *src);
MS_DLL_EXPORT int msCopyProjectionExtended(projectionObj *dst,
const projectionObj *src,
- char **args, int num_args);
+ const char *const *args,
+ int num_args);
int msCopyExpression(expressionObj *dst, const expressionObj *src);
int msCopyProjection(projectionObj *dst, const projectionObj *src);
MS_DLL_EXPORT int msCopyRasterBuffer(rasterBufferObj *dst,
=====================================
src/mapstring.cpp
=====================================
@@ -2515,7 +2515,7 @@ int msStringBufferAppend(msStringBuffer *sb, const char *pszAppendedString) {
if (sb->length + nAppendLen >= sb->alloc_size) {
size_t newAllocSize1 = sb->alloc_size + sb->alloc_size / 3;
size_t newAllocSize2 = sb->length + nAppendLen + 1;
- size_t newAllocSize = MAX(newAllocSize1, newAllocSize2);
+ size_t newAllocSize = std::max(newAllocSize1, newAllocSize2);
void *newStr = realloc(sb->str, newAllocSize);
if (newStr == NULL) {
msSetError(MS_MEMERR, "Not enough memory", "msStringBufferAppend()");
=====================================
src/mapuvraster.cpp
=====================================
@@ -57,42 +57,48 @@
#define MSUVRASTER_LAT "lat"
#define MSUVRASTER_LATINDEX -107
-typedef struct {
+struct uvRasterLayerInfo {
/* query cache results */
- int query_results;
+ int query_results = 0;
- int refcount;
+ int refcount = 0;
- float *u; /* u values */
- float *v; /* v values */
- int width;
- int height;
- rectObj extent;
- int next_shape;
+ float *u = nullptr; /* u values */
+ float *v = nullptr; /* v values */
+ int width = 0;
+ int height = 0;
+ rectObj extent{};
+ int next_shape = 0;
/* To improve performance of GetShape() when queried on increasing shapeindex
*/
- long last_queried_shapeindex; // value in [0, query_results[ range
- size_t last_raster_off; // value in [0, width*height[ range
+ long last_queried_shapeindex = 0; // value in [0, query_results[ range
+ size_t last_raster_off = 0; // value in [0, width*height[ range
- bool needsLonLat;
- reprojectionObj *reprojectorToLonLat;
+ bool needsLonLat = false;
+ reprojectionObj *reprojectorToLonLat = nullptr;
- mapObj
- *mapToUseForWhichShapes; /* set if the map->extent and map->projection are
- valid in msUVRASTERLayerWhichShapes() */
+ /* set if the map->extent and map->projection are
+ valid in msUVRASTERLayerWhichShapes() */
+ mapObj *mapToUseForWhichShapes = nullptr;
-} uvRasterLayerInfo;
+ std::string timestring{};
+ std::string timefield{};
+};
+
+static uvRasterLayerInfo *getLayerInfo(layerObj *layer) {
+ return static_cast<uvRasterLayerInfo *>(layer->layerinfo);
+}
void msUVRASTERLayerUseMapExtentAndProjectionForNextWhichShapes(layerObj *layer,
mapObj *map) {
- uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *)layer->layerinfo;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
uvlinfo->mapToUseForWhichShapes = map;
}
static int msUVRASTERLayerInitItemInfo(layerObj *layer) {
- uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *)layer->layerinfo;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
int i;
int *itemindexes;
int failed = 0;
@@ -154,19 +160,14 @@ void msUVRASTERLayerFreeItemInfo(layerObj *layer) {
}
static void msUVRasterLayerInfoInitialize(layerObj *layer) {
- uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *)layer->layerinfo;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
if (uvlinfo != NULL)
return;
- uvlinfo = (uvRasterLayerInfo *)msSmallCalloc(1, sizeof(uvRasterLayerInfo));
+ uvlinfo = new uvRasterLayerInfo;
layer->layerinfo = uvlinfo;
- uvlinfo->u = NULL;
- uvlinfo->v = NULL;
- uvlinfo->width = 0;
- uvlinfo->height = 0;
-
/* Set attribute type to Real, unless the user has explicitly set */
/* something else. */
{
@@ -189,7 +190,7 @@ static void msUVRasterLayerInfoInitialize(layerObj *layer) {
static void msUVRasterLayerInfoFree(layerObj *layer)
{
- uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *)layer->layerinfo;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
if (uvlinfo == NULL)
return;
@@ -201,7 +202,7 @@ static void msUVRasterLayerInfoFree(layerObj *layer)
msProjectDestroyReprojector(uvlinfo->reprojectorToLonLat);
}
- free(uvlinfo);
+ delete uvlinfo;
layer->layerinfo = NULL;
}
@@ -213,7 +214,7 @@ int msUVRASTERLayerOpen(layerObj *layer) {
if (layer->layerinfo == NULL)
return MS_FAILURE;
- uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *)layer->layerinfo;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
uvlinfo->refcount = uvlinfo->refcount + 1;
@@ -227,7 +228,7 @@ int msUVRASTERLayerIsOpen(layerObj *layer) {
}
int msUVRASTERLayerClose(layerObj *layer) {
- uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *)layer->layerinfo;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
if (uvlinfo != NULL) {
uvlinfo->refcount--;
@@ -239,7 +240,7 @@ int msUVRASTERLayerClose(layerObj *layer) {
}
int msUVRASTERLayerGetItems(layerObj *layer) {
- uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *)layer->layerinfo;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
if (uvlinfo == NULL)
return MS_FAILURE;
@@ -273,7 +274,7 @@ static char **msUVRASTERGetValues(layerObj *layer, float u, float v,
char tmp[100];
float size_scale;
int *itemindexes = (int *)layer->iteminfo;
- uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *)layer->layerinfo;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
double lon = HUGE_VAL;
double lat = HUGE_VAL;
@@ -452,7 +453,7 @@ rectObj msUVRASTERGetSearchRect(layerObj *layer, mapObj *map) {
}
int msUVRASTERLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) {
- uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *)layer->layerinfo;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
imageObj *image_tmp;
outputFormatObj *outputformat = NULL;
mapObj *map_tmp;
@@ -753,7 +754,26 @@ int msUVRASTERLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) {
*/
saved_layer_mask = layer->mask;
layer->mask = NULL;
- ret = msDrawRasterLayerLow(map_tmp, layer, image_tmp, NULL);
+
+ if (layer->tileindex) {
+ expressionObj old_filter;
+ if (!uvlinfo->timestring.empty()) {
+ msInitExpression(&old_filter);
+ msCopyExpression(&old_filter, &layer->filter); /* save existing filter */
+ msFreeExpression(&layer->filter);
+ msLayerMakeBackticsTimeFilter(layer, uvlinfo->timestring.c_str(),
+ uvlinfo->timefield.c_str());
+ }
+
+ ret = msDrawRasterLayerLow(map_tmp, layer, image_tmp, NULL);
+
+ if (!uvlinfo->timestring.empty()) {
+ msCopyExpression(&layer->filter, &old_filter); /* restore old filter */
+ msFreeExpression(&old_filter);
+ }
+ } else {
+ ret = msDrawRasterLayerLow(map_tmp, layer, image_tmp, NULL);
+ }
/* restore layer attributes if we went through the above on-the-fly VRT */
if (oldLayerData) {
@@ -825,7 +845,7 @@ int msUVRASTERLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) {
int msUVRASTERLayerGetShape(layerObj *layer, shapeObj *shape,
resultObj *record) {
- uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *)layer->layerinfo;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
lineObj line;
pointObj point;
const long shapeindex = record->shapeindex;
@@ -889,7 +909,7 @@ int msUVRASTERLayerGetShape(layerObj *layer, shapeObj *shape,
}
int msUVRASTERLayerNextShape(layerObj *layer, shapeObj *shape) {
- uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *)layer->layerinfo;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
if (uvlinfo->next_shape < 0 ||
uvlinfo->next_shape >= uvlinfo->query_results) {
@@ -1029,12 +1049,20 @@ int msUVRASTERLayerSetTimeFilter(layerObj *layer, const char *timestring,
/* -------------------------------------------------------------------- */
/* If we are using a local shapefile as our tileindex (that is */
/* to say, the tileindex name is not of another layer), then we */
- /* just install a backtics style filter on the raster layer. */
- /* This is propagated to the "working layer" created for the */
- /* tileindex by code in mapraster.c. */
+ /* will install a backtics style filter later. */
/* -------------------------------------------------------------------- */
- if (tilelayerindex == -1)
- return msLayerMakeBackticsTimeFilter(layer, timestring, timefield);
+ if (tilelayerindex == -1) {
+ if (layer->layerinfo == NULL)
+ msUVRasterLayerInfoInitialize(layer);
+ if (layer->layerinfo == NULL)
+ return MS_FAILURE;
+ uvRasterLayerInfo *uvlinfo = getLayerInfo(layer);
+ if (timestring)
+ uvlinfo->timestring = timestring;
+ if (timefield)
+ uvlinfo->timefield = timefield;
+ return MS_SUCCESS;
+ }
/* -------------------------------------------------------------------- */
/* Otherwise we invoke the tileindex layers SetTimeFilter */
=====================================
src/mapwcs.cpp
=====================================
@@ -1970,7 +1970,7 @@ void msWCSApplyDatasetMetadataAsCreationOptions(layerObj *lp,
int nDstBand = i + 1;
GDALRasterBandH hBand = GDALGetRasterBand(hDS, nSrcBand);
if (hBand) {
- char **papszMD = GDALGetMetadata(hBand, NULL);
+ CSLConstList papszMD = GDALGetMetadata(hBand, NULL);
const char *pszMDI = CSLFetchNameValue(papszMD, "GRIB_IDS");
// Make sure it is a GRIB2 band
if (pszMDI) {
@@ -2307,9 +2307,9 @@ void msWCSApplySourceDatasetMetadata(layerObj *lp, outputFormatObj *format,
}
{
- char **papszMD = GDALGetMetadata(hDS, NULL);
+ CSLConstList papszMD = GDALGetMetadata(hDS, NULL);
if (papszMD) {
- for (char **papszIter = papszMD; *papszIter; ++papszIter) {
+ for (CSLConstList papszIter = papszMD; *papszIter; ++papszIter) {
// Copy netCDF global attributes, as well as the ones
// of the extra dimension for 3D netCDF files
if (STARTS_WITH(*papszIter, "NC_GLOBAL#") ||
@@ -2334,9 +2334,9 @@ void msWCSApplySourceDatasetMetadata(layerObj *lp, outputFormatObj *format,
int nDstBand = i + 1;
GDALRasterBandH hBand = GDALGetRasterBand(hDS, nSrcBand);
if (hBand) {
- char **papszMD = GDALGetMetadata(hBand, NULL);
+ CSLConstList papszMD = GDALGetMetadata(hBand, NULL);
if (papszMD) {
- for (char **papszIter = papszMD; *papszIter; ++papszIter) {
+ for (CSLConstList papszIter = papszMD; *papszIter; ++papszIter) {
char *pszKey = nullptr;
const char *pszValue = CPLParseNameValue(*papszIter, &pszKey);
if (pszKey && pszValue && !EQUAL(pszKey, "grid_name") &&
=====================================
src/mapwcs20.cpp
=====================================
@@ -39,6 +39,7 @@
#include "mapows.h"
#include "mapwcs.h"
#include "mapgdal.h"
+#include <cmath>
#include <float.h>
#include "gdal.h"
#include "cpl_port.h"
@@ -4641,14 +4642,16 @@ this request. Check wcs/ows_enable_request settings.",
subsetInImageProj.maxy =
MS_MIN(subsetInImageProj.maxy, layer->extent.maxy);
{
- double total = ABS(layer->extent.maxx - layer->extent.minx);
- double part = ABS(subsetInImageProj.maxx - subsetInImageProj.minx);
+ double total = std::abs(layer->extent.maxx - layer->extent.minx);
+ double part =
+ std::abs(subsetInImageProj.maxx - subsetInImageProj.minx);
widthFromComputationInImageCRS =
MS_NINT((part * map->width) / total);
}
{
- double total = ABS(layer->extent.maxy - layer->extent.miny);
- double part = ABS(subsetInImageProj.maxy - subsetInImageProj.miny);
+ double total = std::abs(layer->extent.maxy - layer->extent.miny);
+ double part =
+ std::abs(subsetInImageProj.maxy - subsetInImageProj.miny);
heightFromComputationInImageCRS =
MS_NINT((part * map->height) / total);
}
@@ -4656,6 +4659,15 @@ this request. Check wcs/ows_enable_request settings.",
}
msProjectRect(&imageProj, &subsetProj, &(layer->extent));
+ if (msProjIsGeographicCRS(&subsetProj)) {
+ if (layer->extent.minx > 180 && subsets.maxx <= 180) {
+ layer->extent.minx -= 360;
+ layer->extent.maxx -= 360;
+ } else if (layer->extent.maxx < -180 && subsets.minx >= -180) {
+ layer->extent.minx += 360;
+ layer->extent.maxx += 360;
+ }
+ }
map->extent = layer->extent;
msFreeProjection(&(map->projection));
map->projection = subsetProj;
@@ -4710,10 +4722,10 @@ this request. Check wcs/ows_enable_request settings.",
} else {
if (widthFromComputationInImageCRS != 0) {
params->width = widthFromComputationInImageCRS;
- } else if (ABS(bbox.maxx - bbox.minx) !=
- ABS(map->extent.maxx - map->extent.minx)) {
- double total = ABS(map->extent.maxx - map->extent.minx),
- part = ABS(bbox.maxx - bbox.minx);
+ } else if (std::abs(bbox.maxx - bbox.minx) !=
+ std::abs(map->extent.maxx - map->extent.minx)) {
+ double total = std::abs(map->extent.maxx - map->extent.minx),
+ part = std::abs(bbox.maxx - bbox.minx);
params->width = MS_NINT((part * map->width) / total);
} else {
params->width = map->width;
@@ -4735,10 +4747,10 @@ this request. Check wcs/ows_enable_request settings.",
} else {
if (heightFromComputationInImageCRS != 0) {
params->height = heightFromComputationInImageCRS;
- } else if (ABS(bbox.maxy - bbox.miny) !=
- ABS(map->extent.maxy - map->extent.miny)) {
- double total = ABS(map->extent.maxy - map->extent.miny),
- part = ABS(bbox.maxy - bbox.miny);
+ } else if (std::abs(bbox.maxy - bbox.miny) !=
+ std::abs(map->extent.maxy - map->extent.miny)) {
+ double total = std::abs(map->extent.maxy - map->extent.miny),
+ part = std::abs(bbox.maxy - bbox.miny);
params->height = MS_NINT((part * map->height) / total);
} else {
params->height = map->height;
=====================================
src/mapwms.cpp
=====================================
@@ -3028,8 +3028,32 @@ void msWMSPrintNestedGroups(mapObj *map, int nVersion, char *pabLayerProcessed,
: "");
msIO_printf("%s <Name>%s</Name>\n", indent.c_str(),
nestedGroups[index][level]);
- msIO_printf("%s <Title>%s</Title>\n", indent.c_str(),
- nestedGroups[index][level]);
+
+ {
+ const char *value;
+ if ((value = msOWSLookupMetadataWithLanguage(
+ &(GET_LAYER(map, index)->metadata), "MO", "GROUP_TITLE",
+ validated_language))) {
+ char *encoded = msEncodeHTMLEntities(value);
+ msIO_printf("%s <Title>%s</Title>\n", indent.c_str(), encoded);
+ msFree(encoded);
+ } else {
+ msIO_printf("%s <Title>%s</Title>\n", indent.c_str(),
+ nestedGroups[index][level]);
+ }
+ }
+ {
+ const char *value;
+ if ((value = msOWSLookupMetadataWithLanguage(
+ &(GET_LAYER(map, index)->metadata), "MO", "GROUP_ABSTRACT",
+ validated_language))) {
+ char *encoded = msEncodeHTMLEntities(value);
+ msIO_printf("%s <Abstract>%s</Abstract>\n", indent.c_str(),
+ encoded);
+ msFree(encoded);
+ }
+ }
+
groupAdded = true;
}
View it on GitLab: https://salsa.debian.org/debian-gis-team/mapserver/-/commit/209dc6af1ae010c96e1bb045e3fd2cc325583b62
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/mapserver/-/commit/209dc6af1ae010c96e1bb045e3fd2cc325583b62
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260323/939b0d53/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list