使用GDAL对DEM进行彩色渲染

    在之前的博客中,我们已经看到了gdal对dem数据的强大的处理功能,其中除了坡度坡向等,还有一个比较厉害的,就是使用DEM生成一个彩色的图像。之前关于这方面也翻译了几篇博客,详见《使用GDAL对DEM渲染处理流程》、使用阿富汗和巴基斯坦地区的SRTM数据生成山体阴影和彩色地形图》和使用gdaldem创建彩色地形图和坡度阴影——thematicmapping.org译文(三)》,不过这些都是使用的说明。

把gdaldem的源代码进行了整理,整理了一个使用dem数据生成彩色图像的函数,函数的定义如下。关于第四个参数,sColorMode是个枚举值,一共有三个值,默认的是使用线性插值方式,还有两个是最邻近和严格插值。线性插值就是根据你指定的颜色映射关系,把没有指定的高程值,使用颜色映射关系中最近的两个颜色按照线性插值进行处理,得到最后的颜色;而最邻近就是找到最近的一个颜色,而严格插值就是所有的高程数据都必须对应一个颜色值,要不然就是黑色的。

	/**
	* @brief DEM Color Relief(DEM颜色渲染)
	* @param pszSrcFilename		输入文件路径
	* @param pszColorTextFile	输入颜色映射文件
	* 颜色映射文件的格式是:“高程值 red green blue”,如:“1022 255 125 32”
	* @param pszDstFilename		输出文件路径
	* @param sColorMode			颜色插值模式,默认为COLOR_SELECTION_INTERPOLATE
	* @param bAddAlpha			是否添加Alpha通道,默认为不加
	* @param bComputeAtEdges	是否计算边界,默认为不计算
	* @param pszFormat			输出文件格式,详细参考GDAL支持数据类型
	* @param pProcess			进度条指针
	* @return 返回值,表示计算过程中出现的各种错误信息
	*/
	int IMGALG_API DemColorReliefconst char* pszSrcFilename, const char* pszColorTextFile, const char* pszDstFilename, 
		ColorSelectionMode sColorMode = COLOR_SELECTION_INTERPOLATE, bool bAddAlpha = false,
		bool bComputeAtEdges = false, const char *pszFormat = "GTiff", CProcessBase* pProcess = NULL);

下面是源代码,是从gdal\apps\gdaldem.cpp中摘的,不想用下面的,自己可以去这个文件里面自己去找。具体的代码如下:

#pragma region GDALColorRelief
/************************************************************************/
/*                      GDALColorRelief)                               */
/************************************************************************/

/**
* @brief 颜色结构体
*/
typedef struct
{
	/*! 值 */
	double dfVal;
	/*! R */
	int nR;
	/*! G */
	int nG;
	/*! B */
	int nB;
	/*! A */
	int nA;
} ColorAssociation;

static int GDALColorReliefSortColorsconst void* pA, const void* pB)
{
	ColorAssociation* pC1 = ColorAssociation*)pA;
	ColorAssociation* pC2 = ColorAssociation*)pB;
	return pC1->dfVal < pC2->dfVal) ? -1 :
		pC1->dfVal == pC2->dfVal) ? 0 : 1;
}


static int GDALColorReliefGetRGBA ColorAssociation* pasColorAssociation,
								   int nColorAssociation,
								   double dfVal,
								   ColorSelectionMode eColorSelectionMode,
								   int* pnR,
								   int* pnG,
								   int* pnB,
								   int* pnA)
{
	int i;
	int lower = 0;
	int upper = nColorAssociation - 1;
	int mid;

	/* Find the index of the first element in the LUT input array that */
	/* is not smaller than the dfVal value. */
	whileTRUE)
	{
		mid = lower + upper) / 2;
		if upper - lower <= 1)
		{
			if dfVal < pasColorAssociation[lower].dfVal)
				i = lower;
			else if dfVal < pasColorAssociation[upper].dfVal)
				i = upper;
			else
				i = upper + 1;
			break;
		}
		else if pasColorAssociation[mid].dfVal >= dfVal)
		{
			upper = mid;
		}
		else
		{
			lower = mid;
		}
	}

	if i == 0)
	{
		if eColorSelectionMode == COLOR_SELECTION_EXACT_ENTRY &&
			pasColorAssociation[0].dfVal != dfVal)
		{
			*pnR = 0;
			*pnG = 0;
			*pnB = 0;
			*pnA = 0;
			return FALSE;
		}
		else
		{
			*pnR = pasColorAssociation[0].nR;
			*pnG = pasColorAssociation[0].nG;
			*pnB = pasColorAssociation[0].nB;
			*pnA = pasColorAssociation[0].nA;
			return TRUE;
		}
	}
	else if i == nColorAssociation)
	{
		if eColorSelectionMode == COLOR_SELECTION_EXACT_ENTRY &&
			pasColorAssociation[i-1].dfVal != dfVal)
		{
			*pnR = 0;
			*pnG = 0;
			*pnB = 0;
			*pnA = 0;
			return FALSE;
		}
		else
		{
			*pnR = pasColorAssociation[i-1].nR;
			*pnG = pasColorAssociation[i-1].nG;
			*pnB = pasColorAssociation[i-1].nB;
			*pnA = pasColorAssociation[i-1].nA;
			return TRUE;
		}
	}
	else
	{
		if eColorSelectionMode == COLOR_SELECTION_EXACT_ENTRY &&
			pasColorAssociation[i-1].dfVal != dfVal)
		{
			*pnR = 0;
			*pnG = 0;
			*pnB = 0;
			*pnA = 0;
			return FALSE;
		}

		if eColorSelectionMode == COLOR_SELECTION_NEAREST_ENTRY &&
			pasColorAssociation[i-1].dfVal != dfVal)
		{
			int index;
			if dfVal - pasColorAssociation[i-1].dfVal <
				pasColorAssociation[i].dfVal - dfVal)
				index = i -1;
			else
				index = i;

			*pnR = pasColorAssociation[index].nR;
			*pnG = pasColorAssociation[index].nG;
			*pnB = pasColorAssociation[index].nB;
			*pnA = pasColorAssociation[index].nA;
			return TRUE;
		}

		double dfRatio = dfVal - pasColorAssociation[i-1].dfVal) /
			pasColorAssociation[i].dfVal - pasColorAssociation[i-1].dfVal);
		*pnR = int)0.45 + pasColorAssociation[i-1].nR + dfRatio *
			pasColorAssociation[i].nR - pasColorAssociation[i-1].nR));
		if *pnR < 0) *pnR = 0;
		else if *pnR > 255) *pnR = 255;
		*pnG = int)0.45 + pasColorAssociation[i-1].nG + dfRatio *
			pasColorAssociation[i].nG - pasColorAssociation[i-1].nG));
		if *pnG < 0) *pnG = 0;
		else if *pnG > 255) *pnG = 255;
		*pnB = int)0.45 + pasColorAssociation[i-1].nB + dfRatio *
			pasColorAssociation[i].nB - pasColorAssociation[i-1].nB));
		if *pnB < 0) *pnB = 0;
		else if *pnB > 255) *pnB = 255;
		*pnA = int)0.45 + pasColorAssociation[i-1].nA + dfRatio *
			pasColorAssociation[i].nA - pasColorAssociation[i-1].nA));
		if *pnA < 0) *pnA = 0;
		else if *pnA > 255) *pnA = 255;

		return TRUE;
	}
}

/* dfPct : percentage between 0 and 1 */
static double GDALColorReliefGetAbsoluteValFromPctGDALRasterBandH hSrcBand,
												   double dfPct)
{
	double dfMin, dfMax;
	int bSuccessMin, bSuccessMax;
	dfMin = GDALGetRasterMinimumhSrcBand, &bSuccessMin);
	dfMax = GDALGetRasterMaximumhSrcBand, &bSuccessMax);
	if !bSuccessMin || !bSuccessMax)
	{
		double dfMean, dfStdDev;
		fprintfstderr, "Computing source raster statistics...\n");
		GDALComputeRasterStatisticshSrcBand, FALSE, &dfMin, &dfMax,
			&dfMean, &dfStdDev, NULL, NULL);
	}
	return dfMin + dfPct * dfMax - dfMin);
}

/**
* @brief 名称颜色
*/
typedef struct
{
	/*! 名称 */
	const char *name;
	/*! RGB颜色R */
	float r;
	/*! RGB颜色G */
	float g;
	/*! RGB颜色B */
	float b;
} NamedColor;

static const NamedColor namedColors[] = {
	{ "white",   1.00, 1.00, 1.00 },
	{ "black",   0.00, 0.00, 0.00 },
	{ "red",     1.00, 0.00, 0.00 },
	{ "green",   0.00, 1.00, 0.00 },
	{ "blue",    0.00, 0.00, 1.00 },
	{ "yellow",  1.00, 1.00, 0.00 },
	{ "magenta", 1.00, 0.00, 1.00 },
	{ "cyan",    0.00, 1.00, 1.00 },
	{ "aqua",    0.00, 0.75, 0.75 },
	{ "grey",    0.75, 0.75, 0.75 },
	{ "gray",    0.75, 0.75, 0.75 },
	{ "orange",  1.00, 0.50, 0.00 },
	{ "brown",   0.75, 0.50, 0.25 },
	{ "purple",  0.50, 0.00, 1.00 },
	{ "violet",  0.50, 0.00, 1.00 },
	{ "indigo",  0.00, 0.50, 1.00 },
};				 

static
int GDALColorReliefFindNamedColorconst char *pszColorName, int *pnR, int *pnG, int *pnB)
{
	unsigned int i;

	*pnR = *pnG = *pnB = 0;
	for i = 0; i < sizeofnamedColors) / sizeofnamedColors[0]); i++)
	{
		if EQUALpszColorName, namedColors[i].name))
		{
			*pnR = int)255. * namedColors[i].r);
			*pnG = int)255. * namedColors[i].g);
			*pnB = int)255. * namedColors[i].b);
			return TRUE;
		}
	}
	return FALSE;
}

static
ColorAssociation* GDALColorReliefParseColorFileGDALRasterBandH hSrcBand,
												const char* pszColorFilename,
												int* pnColors)
{
	FILE* fpColorFile = VSIFOpenLpszColorFilename, "rt");
	if fpColorFile == NULL)
	{
		CPLErrorCE_Failure, CPLE_AppDefined, "Cannot find %s", pszColorFilename);
		*pnColors = 0;
		return NULL;
	}

	ColorAssociation* pasColorAssociation = NULL;
	int nColorAssociation = 0;

	int bSrcHasNoData = FALSE;
	double dfSrcNoDataValue = GDALGetRasterNoDataValuehSrcBand, &bSrcHasNoData);

	const char* pszLine;
	while pszLine = CPLReadLineLfpColorFile)) != NULL)
	{
		char** papszFields = CSLTokenizeStringComplexpszLine, " ,\t:", 
			FALSE, FALSE );
		/* Skip comment lines */
		int nTokens = CSLCountpapszFields);
		if nTokens >= 2 &&
			papszFields[0][0] != '#' &&
			papszFields[0][0] != '/')
		{
			pasColorAssociation =
				ColorAssociation*)CPLReallocpasColorAssociation,
				nColorAssociation + 1) * sizeofColorAssociation));
			if EQUALpapszFields[0], "nv") && bSrcHasNoData)
				pasColorAssociation[nColorAssociation].dfVal = dfSrcNoDataValue;
			else if strlenpapszFields[0]) > 1 && papszFields[0][strlenpapszFields[0])-1] == '%')
			{
				double dfPct = atofpapszFields[0]) / 100.;
				if dfPct < 0.0 || dfPct > 1.0)
				{
					CPLErrorCE_Failure, CPLE_AppDefined,
						"Wrong value for a percentage : %s", papszFields[0]);
					CSLDestroypapszFields);
					VSIFCloseLfpColorFile);
					CPLFreepasColorAssociation);
					*pnColors = 0;
					return NULL;
				}
				pasColorAssociation[nColorAssociation].dfVal =
					GDALColorReliefGetAbsoluteValFromPcthSrcBand, dfPct);
			}
			else
				pasColorAssociation[nColorAssociation].dfVal = atofpapszFields[0]);

			if nTokens >= 4)
			{
				pasColorAssociation[nColorAssociation].nR = atoipapszFields[1]);
				pasColorAssociation[nColorAssociation].nG = atoipapszFields[2]);
				pasColorAssociation[nColorAssociation].nB = atoipapszFields[3]);
				pasColorAssociation[nColorAssociation].nA =
					CSLCountpapszFields) >= 5 ) ? atoipapszFields[4]) : 255;
			}
			else
			{
				int nR, nG, nB;
				if !GDALColorReliefFindNamedColorpapszFields[1], &nR, &nG, &nB))
				{
					CPLErrorCE_Failure, CPLE_AppDefined,
						"Unknown color : %s", papszFields[1]);
					CSLDestroypapszFields);
					VSIFCloseLfpColorFile);
					CPLFreepasColorAssociation);
					*pnColors = 0;
					return NULL;
				}
				pasColorAssociation[nColorAssociation].nR = nR;
				pasColorAssociation[nColorAssociation].nG = nG;
				pasColorAssociation[nColorAssociation].nB = nB;
				pasColorAssociation[nColorAssociation].nA =
					CSLCountpapszFields) >= 3 ) ? atoipapszFields[2]) : 255;
			}

			nColorAssociation ++;
		}
		CSLDestroypapszFields);
	}
	VSIFCloseLfpColorFile);

	if nColorAssociation == 0)
	{
		CPLErrorCE_Failure, CPLE_AppDefined,
			"No color association found in %s", pszColorFilename);
		*pnColors = 0;
		return NULL;
	}

	qsortpasColorAssociation, nColorAssociation,
		sizeofColorAssociation), GDALColorReliefSortColors);

	*pnColors = nColorAssociation;
	return pasColorAssociation;
}

static
GByte* GDALColorReliefPrecomputeGDALRasterBandH hSrcBand,
								 ColorAssociation* pasColorAssociation,
								 int nColorAssociation,
								 ColorSelectionMode eColorSelectionMode,
								 int* pnIndexOffset)
{
	GDALDataType eDT = GDALGetRasterDataTypehSrcBand);
	GByte* pabyPrecomputed = NULL;
	int nIndexOffset = eDT == GDT_Int16) ? 32768 : 0;
	*pnIndexOffset = nIndexOffset;
	int nXSize = GDALGetRasterBandXSizehSrcBand);
	int nYSize = GDALGetRasterBandXSizehSrcBand);
	if eDT == GDT_Byte ||
		eDT == GDT_Int16 || eDT == GDT_UInt16) && nXSize * nYSize > 65536))
	{
		int iMax = eDT == GDT_Byte) ? 256: 65536;
		pabyPrecomputed = GByte*) VSIMalloc4 * iMax);
		if pabyPrecomputed)
		{
			int i;
			fori=0; i<iMax; i++)
			{
				int nR, nG, nB, nA;
				GDALColorReliefGetRGBA  pasColorAssociation,
					nColorAssociation,
					i - nIndexOffset,
					eColorSelectionMode,
					&nR, &nG, &nB, &nA);
				pabyPrecomputed[4 * i] = GByte) nR;
				pabyPrecomputed[4 * i + 1] = GByte) nG;
				pabyPrecomputed[4 * i + 2] = GByte) nB;
				pabyPrecomputed[4 * i + 3] = GByte) nA;
			}
		}
	}
	return pabyPrecomputed;
}

CPLErr GDALColorRelief GDALRasterBandH hSrcBand,
						GDALRasterBandH hDstBand1,
						GDALRasterBandH hDstBand2,
						GDALRasterBandH hDstBand3,
						GDALRasterBandH hDstBand4,
						const char* pszColorFilename,
						ColorSelectionMode eColorSelectionMode,
						GDALProgressFunc pfnProgress,
						void * pProgressData)
{
	CPLErr eErr;

	if hSrcBand == NULL || hDstBand1 == NULL || hDstBand2 == NULL ||
		hDstBand3 == NULL)
		return CE_Failure;

	int nColorAssociation = 0;
	ColorAssociation* pasColorAssociation =
		GDALColorReliefParseColorFilehSrcBand, pszColorFilename,
		&nColorAssociation);
	if pasColorAssociation == NULL)
		return CE_Failure;

	int nXSize = GDALGetRasterBandXSizehSrcBand);
	int nYSize = GDALGetRasterBandYSizehSrcBand);

	if pfnProgress == NULL)
		pfnProgress = GDALDummyProgress;

	int nR = 0, nG = 0, nB = 0, nA = 0;

	/* -------------------------------------------------------------------- */
	/*      Precompute the map from values to RGBA quadruplets              */
	/*      for GDT_Byte, GDT_Int16 or GDT_UInt16                           */
	/* -------------------------------------------------------------------- */
	int nIndexOffset = 0;
	GByte* pabyPrecomputed =
		GDALColorReliefPrecomputehSrcBand,
		pasColorAssociation,
		nColorAssociation,
		eColorSelectionMode,
		&nIndexOffset);

	/* -------------------------------------------------------------------- */
	/*      Initialize progress counter.                                    */
	/* -------------------------------------------------------------------- */

	float* pafSourceBuf = NULL;
	int* panSourceBuf = NULL;
	if pabyPrecomputed)
		panSourceBuf = int *) CPLMallocsizeofint)*nXSize);
	else
		pafSourceBuf = float *) CPLMallocsizeoffloat)*nXSize);
	GByte* pabyDestBuf1  = GByte*) CPLMalloc 4 * nXSize );
	GByte* pabyDestBuf2  =  pabyDestBuf1 + nXSize;
	GByte* pabyDestBuf3  =  pabyDestBuf2 + nXSize;
	GByte* pabyDestBuf4  =  pabyDestBuf3 + nXSize;
	int i, j;

	if !pfnProgress 0.0, NULL, pProgressData ) )
	{
		CPLError CE_Failure, CPLE_UserInterrupt, "User terminated" );
		eErr = CE_Failure;
		goto end;
	}

	for  i = 0; i < nYSize; i++)
	{
		/* Read source buffer */
		eErr = GDALRasterIO   hSrcBand,
			GF_Read,
			0, i,
			nXSize, 1,
			panSourceBuf) ? void*) panSourceBuf : void* )pafSourceBuf,
			nXSize, 1,
			panSourceBuf) ? GDT_Int32 : GDT_Float32,
			0, 0);
		if eErr != CE_None)
			goto end;

		if panSourceBuf)
		{
			for  j = 0; j < nXSize; j++)
			{
				int nIndex = panSourceBuf[j] + nIndexOffset;
				pabyDestBuf1[j] = pabyPrecomputed[4 * nIndex];
				pabyDestBuf2[j] = pabyPrecomputed[4 * nIndex + 1];
				pabyDestBuf3[j] = pabyPrecomputed[4 * nIndex + 2];
				pabyDestBuf4[j] = pabyPrecomputed[4 * nIndex + 3];
			}
		}
		else
		{
			for  j = 0; j < nXSize; j++)
			{
				GDALColorReliefGetRGBA  pasColorAssociation,
					nColorAssociation,
					pafSourceBuf[j],
					eColorSelectionMode,
					&nR,
					&nG,
					&nB,
					&nA);
				pabyDestBuf1[j] = GByte) nR;
				pabyDestBuf2[j] = GByte) nG;
				pabyDestBuf3[j] = GByte) nB;
				pabyDestBuf4[j] = GByte) nA;
			}
		}

		/* -----------------------------------------
		* Write Line to Raster
		*/
		eErr = GDALRasterIOhDstBand1,
			GF_Write,
			0, i, nXSize,
			1, pabyDestBuf1, nXSize, 1, GDT_Byte, 0, 0);
		if eErr != CE_None)
			goto end;

		eErr = GDALRasterIOhDstBand2,
			GF_Write,
			0, i, nXSize,
			1, pabyDestBuf2, nXSize, 1, GDT_Byte, 0, 0);
		if eErr != CE_None)
			goto end;

		eErr = GDALRasterIOhDstBand3,
			GF_Write,
			0, i, nXSize,
			1, pabyDestBuf3, nXSize, 1, GDT_Byte, 0, 0);
		if eErr != CE_None)
			goto end;

		if hDstBand4)
		{
			eErr = GDALRasterIOhDstBand4,
				GF_Write,
				0, i, nXSize,
				1, pabyDestBuf4, nXSize, 1, GDT_Byte, 0, 0);
			if eErr != CE_None)
				goto end;
		}

		if !pfnProgress 1.0 * i+1) / nYSize, NULL, pProgressData ) )
		{
			CPLError CE_Failure, CPLE_UserInterrupt, "User terminated" );
			eErr = CE_Failure;
			goto end;
		}
	}
	pfnProgress 1.0, NULL, pProgressData );
	eErr = CE_None;

end:
	VSIFreepabyPrecomputed);
	CPLFreepafSourceBuf);
	CPLFreepanSourceBuf);
	CPLFreepabyDestBuf1);
	CPLFreepasColorAssociation);

	return eErr;
}
#pragma endregion

上面这部分代码就是渲染的核心函数,下面就是函数的实现代码。下面的代码中如果有函数或者变量没有找到定义,请参考我之前的博客中的内容。

int DemColorReliefconst char* pszSrcFilename, const char* pszColorTextFile, const char* pszDstFilename, 
				   ColorSelectionMode sColorMode, bool bAddAlpha, bool bComputeAtEdges , 
				   const char *pszFormat, CProcessBase* pProcess)
{
	ifpProcess != NULL)
	{
		pProcess->ReSetProcess);
		pProcess->SetMessage"正在计算颜色渲染...");
	}

	int nBand = 1;
	double  adfGeoTransform[6];

	char **papszCreateOptions = NULL;

	GDALDatasetH hSrcDataset = NULL;
	GDALDatasetH hDstDataset = NULL;
	GDALRasterBandH hSrcBand = NULL;
	GDALRasterBandH hDstBand = NULL;
	GDALDriverH hDriver = NULL;

	GDALProgressFunc pfnProgress = ALGTermProgress;
	string strColorFile = "";

	int nXSize = 0;
	int nYSize = 0;

	if pszSrcFilename == NULL )
	{
		ifpProcess != NULL)
			pProcess->SetMessage"源文件路径为空!");

		return RE_FILENOTEXIST;
	}

	if pszColorTextFile == NULL || EQUALpszColorTextFile, ""))
	{
		const char* pszGDAL_Data = CPLGetConfigOption"GDAL_DATA", "data");	//获取GDAL_DATA目录
		strColorFile = stringpszGDAL_Data) + "/dem_color_relief.clr";
	}
	else
		strColorFile = pszColorTextFile;

	if pszDstFilename == NULL )
	{
		ifpProcess != NULL)
			pProcess->SetMessage"输出文件路径为空!");

		return RE_FILENOTEXIST;
	}

	ifFileIsUsedpszDstFilename, pProcess))
		return RE_FILEISUESED;

	GDALAllRegister);

	//打开图像
	hSrcDataset = GDALOpen pszSrcFilename, GA_ReadOnly );
	if hSrcDataset == NULL )
	{
		ifpProcess != NULL)
			pProcess->SetMessage"输入文件不能打开!");

		return RE_FILENOTEXIST;
	}

	nXSize = GDALGetRasterXSizehSrcDataset);
	nYSize = GDALGetRasterYSizehSrcDataset);

	if nBand <= 0 || nBand > GDALGetRasterCounthSrcDataset) )
	{
		ifpProcess != NULL)
			pProcess->SetMessage"指定计算的波段不正确!");

		return RE_PARAMERROR;
	}

	hSrcBand = GDALGetRasterBand hSrcDataset, nBand );
	GDALGetGeoTransformhSrcDataset, adfGeoTransform);

	hDriver = GDALGetDriverByNamepszFormat);
	if hDriver == NULL)
	{
		ifpProcess != NULL)
			pProcess->SetMessage"不能创建制定类型的文件,请检查该文件类型GDAL是否支持创建!");

		GDALClose hSrcDataset );

		return RE_FILENOTSUPPORT;
	}

	//设置输出文件数据类型
	GDALDataType eDstDataType = GDT_Byte;

	int nDstBands = bAddAlpha) ? 4 : 3;

	hDstDataset = GDALCreatehDriver,
		pszDstFilename,
		nXSize,
		nYSize,
		nDstBands,
		eDstDataType,
		papszCreateOptions);

	if hDstDataset == NULL )
	{
		ifpProcess != NULL)
			pProcess->SetMessage"创建输出文件失败,请检查文件路径是否正确!");

		GDALClose hSrcDataset );

		return RE_CREATEFAILED;	//创建图像失败
	}

	hDstBand = GDALGetRasterBand hDstDataset, 1 );

	GDALSetGeoTransformhDstDataset, adfGeoTransform);
	GDALSetProjectionhDstDataset, GDALGetProjectionRefhSrcDataset));

	if GDALColorRelief hSrcBand, 
		GDALGetRasterBandhDstDataset, 1),
		GDALGetRasterBandhDstDataset, 2),
		GDALGetRasterBandhDstDataset, 3),
		bAddAlpha) ? GDALGetRasterBandhDstDataset, 4) : NULL,
		strColorFile.c_str),
		sColorMode,
		pfnProgress, pProcess) != CE_None)
	{
		ifpProcess!=NULL)
		{
			if!pProcess->m_bIsContinue)
			{
				GDALClosehSrcDataset);
				GDALClosehDstDataset);

				GDALDeleteDatasethDstDataset, pszDstFilename);	//删除结果文件

				CSLDestroy papszCreateOptions );

				return RE_USERCANCEL;
			}
		}

		GDALClosehSrcDataset);
		GDALClosehDstDataset);

	GDALDeleteDatasethDstDataset, pszDstFilename);	//删除结果文件
        CSLDestroy papszCreateOptions);
		return RE_FAILED;
	}

	GDALClosehSrcDataset);
	GDALClosehDstDataset);

	CSLDestroy papszCreateOptions );

	return RE_SUCCESS;
}

这里需要说明的是,上面的代码中,DEM渲染的颜色文件是一个可选的参数,因为我自己写了一个颜色映射文件,放在GDAL的data目录下面了。通过这个例子,大家也可以学习怎么使用gdal的data目录里的文件了。

dem_color_relief.clr的内容如下,其实就是之前翻译的那篇文章里面的颜色映射,URL为“http://blog.csdn.net/liminlu0314/article/details/8550410”。

0 110 220 110
900 240 250 160
1300 230 220 170
1900 220 220 220
2500 250 250 250

至此,使用上面的函数就可以对一个DEM数据进行渲染了,下面贴一下处理的结果。使用上面的颜色映射渲染的结果如图2所示;下面还有一组颜色映射,这个颜色更鲜艳一些,渲染后的图如图3所示。

100%	255	0	0	255
45.5%	255	255	0	255
20.5%	0	255	0	255
6.7%	0	250	255	255
3.5%	0	128	255	255
1.7%	0	64	255	255
0%	0	10	255	255
nv	0	0	0	0

图1 原始DEM数据
图2 颜色渲染后的结果
图3 颜色渲染后的结果2

Published by

风君子

独自遨游何稽首 揭天掀地慰生平