最近用GDAL做地图开发,做重投影时遇到“Returned tile does not match expected configuration.”错误
- 地图服务:mapserver;
- c++请求:GDAL;
- 请求链接://GDALDataset* psrcData1 =
(GDALDataset*)GDALOpenEx(“WCS:http://ip:port/mapserv/mapserv?map=dom.map&SERVICE=WCS&VERSION=2.0.0&REQUEST=GetCoverage&CoverageID=dom_layer&FORMAT=image/tiff”,
GDAL_OF_RASTER, nullptr, nullptr, nullptr);
问题原因:
1.GDAL请求WCS数据时,会根据WCS请求中DescribeCoverage返回中的
gml:posx y</gml:pos>
和
<gml:offsetVector srsName=“http://www.opengis.net/def/crs/EPSG/0/4326”>0 0.000005</gml:offsetVector>
重新计算投影,
若mapserv发布的原始tif为地理坐标系,因为<gml:offsetVector >返回值仅仅保留6位小数,精度丢失,导致出现“Returned tile does not match expected configuration.”错误。
2.GDAL请求WCS数据时,会分块请求数据,若源数据的宽和高不能2被整除,也会出现此问题。
解决办法:
原因2的问题暂时没找到解决办法。
原因1的解决办法:修改mapserv源码。mapwcs20.c文件中msWCSCommon20_CreateDomainSe函数,将
psOrigin = xmlNewChild(psGrid, psGmlNs, BAD_CAST "origin", NULL);
{
if (swapAxes == MS_FALSE) {
*snprintf(point, sizeof(point), "%f %f", x0, y0);*
} else {
*snprintf(point, sizeof(point), "%f %f", y0, x0);*
}
psOrigin = xmlNewChild(psOrigin, psGmlNs, BAD_CAST "Point", NULL);
snprintf(id, sizeof(id), "grid_origin_%s", layer->name);
xmlNewNsProp(psOrigin, psGmlNs, BAD_CAST "id", BAD_CAST id);
xmlNewProp(psOrigin, BAD_CAST "srsName", BAD_CAST cm->srs_uri);
xmlNewChild(psOrigin, psGmlNs, BAD_CAST "pos", BAD_CAST point);
}
if (swapAxes == MS_FALSE) {
*snprintf(offsetVector1, sizeof(offsetVector1), "%f 0", resx);
snprintf(offsetVector2, sizeof(offsetVector2), "0 %f", resy);*
} else {
*snprintf(offsetVector1, sizeof(offsetVector1), "0 %f", resx);
snprintf(offsetVector2, sizeof(offsetVector2), "%f 0", resy);*
}
修改为
psOrigin = xmlNewChild(psGrid, psGmlNs, BAD_CAST "origin", NULL);
{
if (swapAxes == MS_FALSE) {
*snprintf(point, sizeof(point), "%.15g %.15g", x0, y0);*
} else {
*snprintf(point, sizeof(point), "%.15g %.15g", y0, x0);*
}
psOrigin = xmlNewChild(psOrigin, psGmlNs, BAD_CAST "Point", NULL);
snprintf(id, sizeof(id), "grid_origin_%s", layer->name);
xmlNewNsProp(psOrigin, psGmlNs, BAD_CAST "id", BAD_CAST id);
xmlNewProp(psOrigin, BAD_CAST "srsName", BAD_CAST cm->srs_uri);
xmlNewChild(psOrigin, psGmlNs, BAD_CAST "pos", BAD_CAST point);
}
if (swapAxes == MS_FALSE) {
*snprintf(offsetVector1, sizeof(offsetVector1), "%.15g 0", resx);
snprintf(offsetVector2, sizeof(offsetVector2), "0 %.15g", resy);*
} else {
*snprintf(offsetVector1, sizeof(offsetVector1), "0 %.15g", resx);
snprintf(offsetVector2, sizeof(offsetVector2), "%.15g 0", resy);*
}