Skip to content

Commit b7fb8e4

Browse files
authored
Merge pull request MapServer#7344 from geographika/raster-labels-int32
Support Float64 and Int32 Raster Labels
2 parents 342b042 + aab8852 commit b7fb8e4

File tree

10 files changed

+175
-37
lines changed

10 files changed

+175
-37
lines changed
20.8 KB
Binary file not shown.
10.6 KB
Binary file not shown.
5.08 KB
Loading
5.08 KB
Loading
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# RUN_PARMS: rasterlabel_int32.png [MAP2IMG] -m [MAPFILE] -i png -l int32 -o [RESULT]
2+
# RUN_PARMS: rasterlabel_float64.png [MAP2IMG] -m [MAPFILE] -i png -l float64 -o [RESULT]
3+
4+
MAP
5+
NAME 'test'
6+
EXTENT 600029.81 628680.39 600319.81 628905.39
7+
SIZE 600 600
8+
IMAGETYPE PNG
9+
PROJECTION
10+
"init=epsg:2157"
11+
END
12+
13+
LAYER
14+
PROJECTION
15+
"init=epsg:2157"
16+
END
17+
NAME "int32"
18+
TYPE POINT
19+
CONNECTIONTYPE RASTERLABEL
20+
STATUS OFF
21+
DATA "data/int32.tif"
22+
CLASS
23+
TEXT (tostring([value],"%.0f"))
24+
LABEL
25+
TYPE TRUETYPE
26+
SIZE 7
27+
END
28+
END
29+
END
30+
31+
LAYER
32+
PROJECTION
33+
"init=epsg:2157"
34+
END
35+
NAME "float64"
36+
TYPE POINT
37+
CONNECTIONTYPE RASTERLABEL
38+
STATUS OFF
39+
DATA "data/float64.tif"
40+
CLASS
41+
TEXT (tostring([value],"%.0f"))
42+
LABEL
43+
TYPE TRUETYPE
44+
SIZE 7
45+
END # label
46+
END # class
47+
END
48+
END

src/mapdrawgdal.c

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,7 +1723,7 @@ msDrawRasterLayerGDAL_RawMode(mapObj *map, layerObj *layer, imageObj *image,
17231723
int *band_list, band_count;
17241724
int i, j, k, band;
17251725
CPLErr eErr;
1726-
float *f_nodatas = NULL;
1726+
double *d_nodatas = NULL;
17271727
unsigned char *b_nodatas = NULL;
17281728
GInt16 *i_nodatas = NULL;
17291729
int got_nodata = FALSE;
@@ -1753,6 +1753,8 @@ msDrawRasterLayerGDAL_RawMode(mapObj *map, layerObj *layer, imageObj *image,
17531753
eDataType = GDT_Int16;
17541754
else if (image->format->imagemode == MS_IMAGEMODE_FLOAT32)
17551755
eDataType = GDT_Float32;
1756+
else if (image->format->imagemode == MS_IMAGEMODE_FLOAT64)
1757+
eDataType = GDT_Float64;
17561758
else if (image->format->imagemode == MS_IMAGEMODE_BYTE)
17571759
eDataType = GDT_Byte;
17581760
else
@@ -1778,11 +1780,12 @@ msDrawRasterLayerGDAL_RawMode(mapObj *map, layerObj *layer, imageObj *image,
17781780
/* -------------------------------------------------------------------- */
17791781
/* Do we have nodata values? */
17801782
/* -------------------------------------------------------------------- */
1781-
f_nodatas = (float *)calloc(band_count, sizeof(float));
1782-
if (f_nodatas == NULL) {
1783+
1784+
d_nodatas = (double *)calloc(band_count, sizeof(double));
1785+
if (d_nodatas == NULL) {
17831786
msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n",
17841787
"msDrawRasterLayerGDAL_RawMode()", __FILE__, __LINE__,
1785-
(unsigned int)(sizeof(float) * band_count));
1788+
(unsigned int)(sizeof(double) * band_count));
17861789
free(band_list);
17871790
return -1;
17881791
}
@@ -1791,33 +1794,33 @@ msDrawRasterLayerGDAL_RawMode(mapObj *map, layerObj *layer, imageObj *image,
17911794
(layer->offsite.red != -1 || layer->offsite.green != -1 ||
17921795
layer->offsite.blue != -1)) {
17931796
if (band_count > 0)
1794-
f_nodatas[0] = layer->offsite.red;
1797+
d_nodatas[0] = layer->offsite.red;
17951798
if (band_count > 1)
1796-
f_nodatas[1] = layer->offsite.green;
1799+
d_nodatas[1] = layer->offsite.green;
17971800
if (band_count > 2)
1798-
f_nodatas[2] = layer->offsite.blue;
1801+
d_nodatas[2] = layer->offsite.blue;
17991802
got_nodata = TRUE;
18001803
}
18011804

18021805
if (!got_nodata) {
18031806
got_nodata = TRUE;
18041807
for (band = 0; band < band_count && got_nodata; band++) {
1805-
f_nodatas[band] = msGetGDALNoDataValue(
1808+
d_nodatas[band] = msGetGDALNoDataValue(
18061809
layer, GDALGetRasterBand(hDS, band_list[band]), &got_nodata);
18071810
}
18081811
}
18091812

18101813
if (!got_nodata) {
1811-
free(f_nodatas);
1812-
f_nodatas = NULL;
1814+
free(d_nodatas);
1815+
d_nodatas = NULL;
18131816
} else if (eDataType == GDT_Byte) {
1814-
b_nodatas = (unsigned char *)f_nodatas;
1817+
b_nodatas = (unsigned char *)d_nodatas;
18151818
for (band = 0; band < band_count; band++)
1816-
b_nodatas[band] = (unsigned char)f_nodatas[band];
1819+
b_nodatas[band] = (unsigned char)d_nodatas[band];
18171820
} else if (eDataType == GDT_Int16) {
1818-
i_nodatas = (GInt16 *)f_nodatas;
1821+
i_nodatas = (GInt16 *)d_nodatas;
18191822
for (band = 0; band < band_count; band++)
1820-
i_nodatas[band] = (GInt16)f_nodatas[band];
1823+
i_nodatas[band] = (GInt16)d_nodatas[band];
18211824
}
18221825

18231826
/* -------------------------------------------------------------------- */
@@ -1829,7 +1832,7 @@ msDrawRasterLayerGDAL_RawMode(mapObj *map, layerObj *layer, imageObj *image,
18291832
msSetError(MS_MEMERR, "Allocating work image of size %dx%d failed.",
18301833
"msDrawRasterLayerGDAL()", dst_xsize, dst_ysize);
18311834
free(band_list);
1832-
free(f_nodatas);
1835+
free(d_nodatas);
18331836
return -1;
18341837
}
18351838

@@ -1843,7 +1846,7 @@ msDrawRasterLayerGDAL_RawMode(mapObj *map, layerObj *layer, imageObj *image,
18431846
msSetError(MS_IOERR, "GDALRasterIO() failed: %s",
18441847
"msDrawRasterLayerGDAL_RawMode()", CPLGetLastErrorMsg());
18451848
free(pBuffer);
1846-
free(f_nodatas);
1849+
free(d_nodatas);
18471850
return -1;
18481851
}
18491852

@@ -1872,7 +1875,7 @@ msDrawRasterLayerGDAL_RawMode(mapObj *map, layerObj *layer, imageObj *image,
18721875
int off = j + i * image->width + band * image->width * image->height;
18731876
int off_mask = j + i * image->width;
18741877

1875-
if ((f_nodatas && ((float *)pBuffer)[k] == f_nodatas[band]) ||
1878+
if ((d_nodatas && ((float *)pBuffer)[k] == d_nodatas[band]) ||
18761879
SKIP_MASK(j, i)) {
18771880
k++;
18781881
continue;
@@ -1881,6 +1884,20 @@ msDrawRasterLayerGDAL_RawMode(mapObj *map, layerObj *layer, imageObj *image,
18811884
image->img.raw_float[off] = ((float *)pBuffer)[k++];
18821885
MS_SET_BIT(image->img_mask, off_mask);
18831886
}
1887+
} else if (image->format->imagemode == MS_IMAGEMODE_FLOAT64) {
1888+
for (j = dst_xoff; j < dst_xoff + dst_xsize; j++) {
1889+
int off = j + i * image->width + band * image->width * image->height;
1890+
int off_mask = j + i * image->width;
1891+
1892+
if ((d_nodatas && ((double *)pBuffer)[k] == d_nodatas[band]) ||
1893+
SKIP_MASK(j, i)) {
1894+
k++;
1895+
continue;
1896+
}
1897+
1898+
image->img.raw_double[off] = ((double *)pBuffer)[k++];
1899+
MS_SET_BIT(image->img_mask, off_mask);
1900+
}
18841901
} else if (image->format->imagemode == MS_IMAGEMODE_BYTE) {
18851902
for (j = dst_xoff; j < dst_xoff + dst_xsize; j++) {
18861903
int off = j + i * image->width + band * image->width * image->height;
@@ -1900,7 +1917,7 @@ msDrawRasterLayerGDAL_RawMode(mapObj *map, layerObj *layer, imageObj *image,
19001917
}
19011918

19021919
free(pBuffer);
1903-
free(f_nodatas);
1920+
free(d_nodatas);
19041921

19051922
return 0;
19061923
}

src/maprasterlabel.cpp

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,20 @@
4242
#define MSRASTERLABEL_VALUE "value"
4343
#define MSRASTERLABEL_VALUEINDEX -100
4444

45+
typedef enum { RASTER_FLOAT, RASTER_DOUBLE } RasterValueType;
46+
4547
typedef struct {
4648

4749
/* query cache results */
4850
int query_results;
4951

5052
int refcount;
5153

52-
float *raster_values; /* raster values */
54+
float *f_raster_values; /* raster values */
55+
double *d_raster_values;
56+
57+
RasterValueType value_type; // flag to check if floats or doubles are used
58+
5359
int width;
5460
int height;
5561
rectObj extent;
@@ -128,7 +134,9 @@ static void msRasterLabelLayerInfoInitialize(layerObj *layer) {
128134
(RasterLabelLayerInfo *)msSmallCalloc(1, sizeof(RasterLabelLayerInfo));
129135
layer->layerinfo = rllinfo;
130136

131-
rllinfo->raster_values = NULL;
137+
rllinfo->value_type = RASTER_FLOAT;
138+
rllinfo->f_raster_values = NULL;
139+
rllinfo->d_raster_values = NULL;
132140
rllinfo->width = 0;
133141
rllinfo->height = 0;
134142

@@ -158,8 +166,8 @@ static void msRasterLabelLayerInfoFree(layerObj *layer)
158166
if (rllinfo == NULL)
159167
return;
160168

161-
free(rllinfo->raster_values);
162-
169+
free(rllinfo->f_raster_values);
170+
free(rllinfo->d_raster_values);
163171
free(rllinfo);
164172

165173
layer->layerinfo = NULL;
@@ -216,7 +224,7 @@ int msRasterLabelLayerGetItems(layerObj *layer) {
216224
/**********************************************************************
217225
* msRasterLabelGetValues()
218226
**********************************************************************/
219-
static char **msRasterLabelGetValues(layerObj *layer, float value) {
227+
static char **msRasterLabelGetValues(layerObj *layer, double value) {
220228
char **values;
221229
int i = 0;
222230
char tmp[100];
@@ -248,6 +256,12 @@ static char **msRasterLabelGetValues(layerObj *layer, float value) {
248256
return values;
249257
}
250258

259+
// Float overload
260+
static char **msRasterLabelGetValues(layerObj *layer, float value) {
261+
// cast float to double and call the double version
262+
return msRasterLabelGetValues(layer, static_cast<double>(value));
263+
}
264+
251265
rectObj msRasterLabelGetSearchRect(layerObj *layer, mapObj *map) {
252266
rectObj searchrect = map->extent;
253267
int bDone = MS_FALSE;
@@ -448,7 +462,19 @@ int msRasterLabelLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) {
448462
outputformat->vtable = NULL;
449463
outputformat->device = NULL;
450464
outputformat->renderer = MS_RENDER_WITH_RAWDATA;
451-
outputformat->imagemode = MS_IMAGEMODE_FLOAT32;
465+
466+
// check type of the first band only to decide output format
467+
switch (GDALGetRasterDataType(GDALGetRasterBand(hDS, 1))) {
468+
case GDT_Int32:
469+
case GDT_Float64:
470+
outputformat->imagemode = MS_IMAGEMODE_FLOAT64;
471+
rllinfo->value_type = RASTER_DOUBLE;
472+
break;
473+
default:
474+
outputformat->imagemode = MS_IMAGEMODE_FLOAT32;
475+
break;
476+
}
477+
452478
msAppendOutputFormat(map_tmp, outputformat);
453479

454480
msCopyHashTable(&map_tmp->configoptions, &layer->map->configoptions);
@@ -726,16 +752,32 @@ int msRasterLabelLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) {
726752
rllinfo->last_queried_shapeindex = 0;
727753
rllinfo->last_raster_off = 0;
728754

729-
free(rllinfo->raster_values);
730-
rllinfo->raster_values =
731-
(float *)msSmallMalloc(sizeof(float) * width * height);
755+
free(rllinfo->f_raster_values);
756+
free(rllinfo->d_raster_values);
732757

733-
for (size_t off = 0; off < static_cast<size_t>(width) * height; ++off) {
734-
if (MS_GET_BIT(image_tmp->img_mask, off)) {
735-
rllinfo->raster_values[off] = image_tmp->img.raw_float[off];
736-
rllinfo->query_results++;
737-
} else
738-
rllinfo->raster_values[off] = std::numeric_limits<float>::quiet_NaN();
758+
if (rllinfo->value_type == RASTER_DOUBLE) {
759+
rllinfo->d_raster_values =
760+
(double *)msSmallMalloc(sizeof(double) * width * height);
761+
762+
for (size_t off = 0; off < static_cast<size_t>(width) * height; ++off) {
763+
if (MS_GET_BIT(image_tmp->img_mask, off)) {
764+
rllinfo->d_raster_values[off] = image_tmp->img.raw_double[off];
765+
rllinfo->query_results++;
766+
} else
767+
rllinfo->d_raster_values[off] =
768+
std::numeric_limits<double>::quiet_NaN();
769+
}
770+
} else {
771+
rllinfo->f_raster_values =
772+
(float *)msSmallMalloc(sizeof(float) * width * height);
773+
774+
for (size_t off = 0; off < static_cast<size_t>(width) * height; ++off) {
775+
if (MS_GET_BIT(image_tmp->img_mask, off)) {
776+
rllinfo->f_raster_values[off] = image_tmp->img.raw_float[off];
777+
rllinfo->query_results++;
778+
} else
779+
rllinfo->f_raster_values[off] = std::numeric_limits<float>::quiet_NaN();
780+
}
739781
}
740782

741783
msFreeImage(image_tmp); /* we do not need the imageObj anymore */
@@ -774,7 +816,15 @@ int msRasterLabelLayerGetShape(layerObj *layer, shapeObj *shape,
774816
: 0;
775817
raster_off < static_cast<size_t>(rllinfo->width) * rllinfo->height;
776818
++raster_off) {
777-
if (!std::isnan(rllinfo->raster_values[raster_off])) {
819+
820+
bool is_valid = false;
821+
if (rllinfo->value_type == RASTER_DOUBLE) {
822+
is_valid = !std::isnan(rllinfo->d_raster_values[raster_off]);
823+
} else {
824+
is_valid = !std::isnan(rllinfo->f_raster_values[raster_off]);
825+
}
826+
827+
if (is_valid) {
778828
if (curshapeindex == shapeindex) {
779829
rllinfo->last_queried_shapeindex = shapeindex;
780830
rllinfo->last_raster_off = raster_off;
@@ -804,8 +854,13 @@ int msRasterLabelLayerGetShape(layerObj *layer, shapeObj *shape,
804854
msComputeBounds(shape);
805855

806856
shape->numvalues = layer->numitems;
807-
shape->values =
808-
msRasterLabelGetValues(layer, rllinfo->raster_values[raster_off]);
857+
if (rllinfo->value_type == RASTER_DOUBLE) {
858+
shape->values =
859+
msRasterLabelGetValues(layer, rllinfo->d_raster_values[raster_off]);
860+
} else {
861+
shape->values =
862+
msRasterLabelGetValues(layer, rllinfo->f_raster_values[raster_off]);
863+
}
809864
shape->index = shapeindex;
810865
shape->resultindex = shapeindex;
811866

src/mapresample.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ static void msSourceSample(imageObj *psSrcImage, rasterBufferObj *rb, int iSrcX,
263263
fValue = psSrcImage->img.raw_float[src_off];
264264

265265
padfPixelSum[band] += fValue * dfWeight;
266+
} else if (psSrcImage->format->imagemode == MS_IMAGEMODE_FLOAT64) {
267+
double dValue;
268+
269+
dValue = psSrcImage->img.raw_double[src_off];
270+
271+
padfPixelSum[band] += dValue * dfWeight;
266272
} else if (psSrcImage->format->imagemode == MS_IMAGEMODE_BYTE) {
267273
int nValue;
268274

@@ -596,6 +602,8 @@ msAverageRasterResampler(imageObj *psSrcImage, rasterBufferObj *src_rb,
596602
(short)(padfPixelSum[band] + 0.5);
597603
} else if (psSrcImage->format->imagemode == MS_IMAGEMODE_FLOAT32) {
598604
psDstImage->img.raw_float[dst_off] = (float)padfPixelSum[band];
605+
} else if (psSrcImage->format->imagemode == MS_IMAGEMODE_FLOAT64) {
606+
psDstImage->img.raw_double[dst_off] = (double)padfPixelSum[band];
599607
} else if (psSrcImage->format->imagemode == MS_IMAGEMODE_BYTE) {
600608
psDstImage->img.raw_byte[dst_off] =
601609
(unsigned char)padfPixelSum[band];

src/mapserver.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,8 @@ enum MS_IMAGEMODE {
677677
MS_IMAGEMODE_FLOAT32,
678678
MS_IMAGEMODE_BYTE,
679679
MS_IMAGEMODE_FEATURE,
680-
MS_IMAGEMODE_NULL
680+
MS_IMAGEMODE_NULL,
681+
MS_IMAGEMODE_FLOAT64
681682
};
682683

683684
enum MS_GEOS_OPERATOR {
@@ -2075,6 +2076,7 @@ struct imageObj {
20752076
char *imagemap;
20762077
short *raw_16bit;
20772078
float *raw_float;
2079+
double *raw_double;
20782080
unsigned char *raw_byte;
20792081
} img;
20802082
ms_bitarray img_mask;

0 commit comments

Comments
 (0)