在之前的博客中,我们已经看到了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 DemColorRelief(const 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 GDALColorReliefSortColors(const 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. */while(TRUE){mid = (lower + upper) / 2;if (upper - lower <= 1){if (dfVal < pasColorAssociation[lower].dfVal)i = lower;else if (dfVal < pasColorAssociation[upper].dfVal)i = upper;elsei = 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;elseindex = 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 GDALColorReliefGetAbsoluteValFromPct(GDALRasterBandH hSrcBand,double dfPct)
{double dfMin, dfMax;int bSuccessMin, bSuccessMax;dfMin = GDALGetRasterMinimum(hSrcBand, &bSuccessMin);dfMax = GDALGetRasterMaximum(hSrcBand, &bSuccessMax);if (!bSuccessMin || !bSuccessMax){double dfMean, dfStdDev;fprintf(stderr, "Computing source raster statistics...\n");GDALComputeRasterStatistics(hSrcBand, 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 GDALColorReliefFindNamedColor(const char *pszColorName, int *pnR, int *pnG, int *pnB)
{unsigned int i;*pnR = *pnG = *pnB = 0;for (i = 0; i < sizeof(namedColors) / sizeof(namedColors[0]); i++){if (EQUAL(pszColorName, 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* GDALColorReliefParseColorFile(GDALRasterBandH hSrcBand,const char* pszColorFilename,int* pnColors)
{FILE* fpColorFile = VSIFOpenL(pszColorFilename, "rt");if (fpColorFile == NULL){CPLError(CE_Failure, CPLE_AppDefined, "Cannot find %s", pszColorFilename);*pnColors = 0;return NULL;}ColorAssociation* pasColorAssociation = NULL;int nColorAssociation = 0;int bSrcHasNoData = FALSE;double dfSrcNoDataValue = GDALGetRasterNoDataValue(hSrcBand, &bSrcHasNoData);const char* pszLine;while ((pszLine = CPLReadLineL(fpColorFile)) != NULL){char** papszFields = CSLTokenizeStringComplex(pszLine, " ,\t:", FALSE, FALSE );/* Skip comment lines */int nTokens = CSLCount(papszFields);if (nTokens >= 2 &&papszFields[0][0] != '#' &&papszFields[0][0] != '/'){pasColorAssociation =(ColorAssociation*)CPLRealloc(pasColorAssociation,(nColorAssociation + 1) * sizeof(ColorAssociation));if (EQUAL(papszFields[0], "nv") && bSrcHasNoData)pasColorAssociation[nColorAssociation].dfVal = dfSrcNoDataValue;else if (strlen(papszFields[0]) > 1 && papszFields[0][strlen(papszFields[0])-1] == '%'){double dfPct = atof(papszFields[0]) / 100.;if (dfPct < 0.0 || dfPct > 1.0){CPLError(CE_Failure, CPLE_AppDefined,"Wrong value for a percentage : %s", papszFields[0]);CSLDestroy(papszFields);VSIFCloseL(fpColorFile);CPLFree(pasColorAssociation);*pnColors = 0;return NULL;}pasColorAssociation[nColorAssociation].dfVal =GDALColorReliefGetAbsoluteValFromPct(hSrcBand, dfPct);}elsepasColorAssociation[nColorAssociation].dfVal = atof(papszFields[0]);if (nTokens >= 4){pasColorAssociation[nColorAssociation].nR = atoi(papszFields[1]);pasColorAssociation[nColorAssociation].nG = atoi(papszFields[2]);pasColorAssociation[nColorAssociation].nB = atoi(papszFields[3]);pasColorAssociation[nColorAssociation].nA =(CSLCount(papszFields) >= 5 ) ? atoi(papszFields[4]) : 255;}else{int nR, nG, nB;if (!GDALColorReliefFindNamedColor(papszFields[1], &nR, &nG, &nB)){CPLError(CE_Failure, CPLE_AppDefined,"Unknown color : %s", papszFields[1]);CSLDestroy(papszFields);VSIFCloseL(fpColorFile);CPLFree(pasColorAssociation);*pnColors = 0;return NULL;}pasColorAssociation[nColorAssociation].nR = nR;pasColorAssociation[nColorAssociation].nG = nG;pasColorAssociation[nColorAssociation].nB = nB;pasColorAssociation[nColorAssociation].nA =(CSLCount(papszFields) >= 3 ) ? atoi(papszFields[2]) : 255;}nColorAssociation ++;}CSLDestroy(papszFields);}VSIFCloseL(fpColorFile);if (nColorAssociation == 0){CPLError(CE_Failure, CPLE_AppDefined,"No color association found in %s", pszColorFilename);*pnColors = 0;return NULL;}qsort(pasColorAssociation, nColorAssociation,sizeof(ColorAssociation), GDALColorReliefSortColors);*pnColors = nColorAssociation;return pasColorAssociation;
}static
GByte* GDALColorReliefPrecompute(GDALRasterBandH hSrcBand,ColorAssociation* pasColorAssociation,int nColorAssociation,ColorSelectionMode eColorSelectionMode,int* pnIndexOffset)
{GDALDataType eDT = GDALGetRasterDataType(hSrcBand);GByte* pabyPrecomputed = NULL;int nIndexOffset = (eDT == GDT_Int16) ? 32768 : 0;*pnIndexOffset = nIndexOffset;int nXSize = GDALGetRasterBandXSize(hSrcBand);int nYSize = GDALGetRasterBandXSize(hSrcBand);if (eDT == GDT_Byte ||((eDT == GDT_Int16 || eDT == GDT_UInt16) && nXSize * nYSize > 65536)){int iMax = (eDT == GDT_Byte) ? 256: 65536;pabyPrecomputed = (GByte*) VSIMalloc(4 * iMax);if (pabyPrecomputed){int i;for(i=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 =GDALColorReliefParseColorFile(hSrcBand, pszColorFilename,&nColorAssociation);if (pasColorAssociation == NULL)return CE_Failure;int nXSize = GDALGetRasterBandXSize(hSrcBand);int nYSize = GDALGetRasterBandYSize(hSrcBand);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 =GDALColorReliefPrecompute(hSrcBand,pasColorAssociation,nColorAssociation,eColorSelectionMode,&nIndexOffset);/* -------------------------------------------------------------------- *//*      Initialize progress counter.                                    *//* -------------------------------------------------------------------- */float* pafSourceBuf = NULL;int* panSourceBuf = NULL;if (pabyPrecomputed)panSourceBuf = (int *) CPLMalloc(sizeof(int)*nXSize);elsepafSourceBuf = (float *) CPLMalloc(sizeof(float)*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 = GDALRasterIO(hDstBand1,GF_Write,0, i, nXSize,1, pabyDestBuf1, nXSize, 1, GDT_Byte, 0, 0);if (eErr != CE_None)goto end;eErr = GDALRasterIO(hDstBand2,GF_Write,0, i, nXSize,1, pabyDestBuf2, nXSize, 1, GDT_Byte, 0, 0);if (eErr != CE_None)goto end;eErr = GDALRasterIO(hDstBand3,GF_Write,0, i, nXSize,1, pabyDestBuf3, nXSize, 1, GDT_Byte, 0, 0);if (eErr != CE_None)goto end;if (hDstBand4){eErr = GDALRasterIO(hDstBand4,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:VSIFree(pabyPrecomputed);CPLFree(pafSourceBuf);CPLFree(panSourceBuf);CPLFree(pabyDestBuf1);CPLFree(pasColorAssociation);return eErr;
}
#pragma endregion

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

int DemColorRelief(const char* pszSrcFilename, const char* pszColorTextFile, const char* pszDstFilename, ColorSelectionMode sColorMode, bool bAddAlpha, bool bComputeAtEdges , const char *pszFormat, CProcessBase* pProcess)
{if(pProcess != 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 ){if(pProcess != NULL)pProcess->SetMessage("源文件路径为空!");return RE_FILENOTEXIST;}if( pszColorTextFile == NULL || EQUAL(pszColorTextFile, "")){const char* pszGDAL_Data = CPLGetConfigOption("GDAL_DATA", "data"); //获取GDAL_DATA目录strColorFile = string(pszGDAL_Data) + "/dem_color_relief.clr";}elsestrColorFile = pszColorTextFile;if( pszDstFilename == NULL ){if(pProcess != NULL)pProcess->SetMessage("输出文件路径为空!");return RE_FILENOTEXIST;}if(FileIsUsed(pszDstFilename, pProcess))return RE_FILEISUESED;GDALAllRegister();//打开图像hSrcDataset = GDALOpen( pszSrcFilename, GA_ReadOnly );if( hSrcDataset == NULL ){if(pProcess != NULL)pProcess->SetMessage("输入文件不能打开!");return RE_FILENOTEXIST;}nXSize = GDALGetRasterXSize(hSrcDataset);nYSize = GDALGetRasterYSize(hSrcDataset);if( nBand <= 0 || nBand > GDALGetRasterCount(hSrcDataset) ){if(pProcess != NULL)pProcess->SetMessage("指定计算的波段不正确!");return RE_PARAMERROR;}hSrcBand = GDALGetRasterBand( hSrcDataset, nBand );GDALGetGeoTransform(hSrcDataset, adfGeoTransform);hDriver = GDALGetDriverByName(pszFormat);if( hDriver == NULL){if(pProcess != NULL)pProcess->SetMessage("不能创建制定类型的文件,请检查该文件类型GDAL是否支持创建!");GDALClose( hSrcDataset );return RE_FILENOTSUPPORT;}//设置输出文件数据类型GDALDataType eDstDataType = GDT_Byte;int nDstBands = (bAddAlpha) ? 4 : 3;hDstDataset = GDALCreate(hDriver,pszDstFilename,nXSize,nYSize,nDstBands,eDstDataType,papszCreateOptions);if( hDstDataset == NULL ){if(pProcess != NULL)pProcess->SetMessage("创建输出文件失败,请检查文件路径是否正确!");GDALClose( hSrcDataset );return RE_CREATEFAILED;    //创建图像失败}hDstBand = GDALGetRasterBand( hDstDataset, 1 );GDALSetGeoTransform(hDstDataset, adfGeoTransform);GDALSetProjection(hDstDataset, GDALGetProjectionRef(hSrcDataset));if (GDALColorRelief (hSrcBand, GDALGetRasterBand(hDstDataset, 1),GDALGetRasterBand(hDstDataset, 2),GDALGetRasterBand(hDstDataset, 3),(bAddAlpha) ? GDALGetRasterBand(hDstDataset, 4) : NULL,strColorFile.c_str(),sColorMode,pfnProgress, pProcess) != CE_None){if(pProcess!=NULL){if(!pProcess->m_bIsContinue){GDALClose(hSrcDataset);GDALClose(hDstDataset);GDALDeleteDataset(hDstDataset, pszDstFilename);  //删除结果文件CSLDestroy( papszCreateOptions );return RE_USERCANCEL;}}GDALClose(hSrcDataset);GDALClose(hDstDataset);GDALDeleteDataset(hDstDataset, pszDstFilename);   //删除结果文件CSLDestroy( papszCreateOptions);return RE_FAILED;}GDALClose(hSrcDataset);GDALClose(hDstDataset);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

使用GDAL对DEM进行彩色渲染相关推荐

  1. 使用DEM生成彩色的立体图像

    在上篇博客中,使用GDAL提供的函数生成彩色渲染图,但是不是立体的.在之前有一篇翻译的博文中可以使用Mapnik进行立体渲染详见"http://blog.csdn.net/liminlu03 ...

  2. 使用GDAL对DEM渲染处理流程

    下面是翻译的一篇国外的博客,没有严格按照原文的字面意思翻译,是按照我自己的理解来进行翻译的,如果有错误,还请大家指正,原文地址是:http://linfiniti.com/2010/12/a-work ...

  3. GDAL使用DEM数据计算山体阴影(Hillshade)

    零.        前言 说起Hillshade,其实就是模拟太阳光照射地形所引起的明暗对比,然后来对地形图进行渲染,使之看起来具有立体效果的一种方式,常用于地图的渲染,如表1所示,具体的可以参考文献 ...

  4. GDAL使用DEM数据计算地形指数

    零.        前言 本文是接上文<GDAL使用DEM数据计算坡度坡向>,还是一篇关于DEM计算地形指数的一篇文章.这里所要计算的地形指数主要包括以下三个指数:地形耐用指数(Terra ...

  5. HTML怎么做成多彩背景,纯html+div+css模拟酷炫彩色渲染背景

    纯html+div+css模拟酷炫彩色渲染背景 www.html.com.cn 出品 html> 纯div+css模拟酷炫彩色渲染背景 /* 自写js */ body{ /*padding:0; ...

  6. GDAL使用DEM数据计算坡度坡向

    零.        前言 之前写过一个3×3的通用模板算子函数的博客<基于GDAL的一个通用的3×3模板函数>,网址:http://blog.csdn.net/liminlu0314/ar ...

  7. 二十八. geotrellis使用 栅格数据色彩渲染(多波段真彩色)

    一.前言 上一篇文章介绍了如何使用Geotrellis渲染单波段的栅格数据,已然很是头疼,这几天不懈努力之后工作又进了一步,整清楚了如何使用Geotrellis将多个(3个)波段的栅格数据渲染成真彩色 ...

  8. 【GDAL】python读取DEM计算坡度与坡向

    利用GDAL读入DEM与Landsat影像,由于DEM是WG84坐标系,Landsat是WGS84坐标系UTM投影,因此处理在实际应用中需要将DEM进行投影转换. 大概分为以下几个步骤: 读取DEM, ...

  9. GDAL读写Tiff、DEM文件

    Gdal库读取和生成图像数据 https://blog.csdn.net/u012273127/article/details/53309750?utm_medium=distribute.pc_re ...

最新文章

  1. JavaWeb总结(六)—Session
  2. Xamarin.Android编译CPU类型选择方式
  3. java从property中取值,JAVA读取PROPERTIES配置文件
  4. BZOJ3028食物——生成函数+泰勒展开
  5. 算法竞赛入门经典(第二版) | 例题5-3 安迪的第一个字典 (紫书牛啤!)(UVa10815,Andy's First Dictionary)
  6. arraylist内存溢出_ArrayList使用内存映射文件
  7. 安装eclipse版本oxygen,及maven导入spring mvc项目并运行
  8. seata实现分布式事务解决方案
  9. 深度学习在其他领域的应用1:密码破解
  10. C++ explicit关键字应用方法详解
  11. 【CV学习笔记】ROI与泛洪填充
  12. 通用无线公共接口cpri学习笔记_11/24
  13. 实现通过Xcode安装到虚拟机后安装iPhone模拟器并安装ipa软件到模拟器上
  14. 系统提示无法删除文件或文件夹的常用解决办法
  15. android 时间大小排序,android collection.sort()根据时间排序list
  16. AirServer7ios苹果手机专用投屏PC电脑工具
  17. “我等了三年,就是想等一个机会!” 谈谈数据团队如何为自己争取资源!
  18. 【推荐算法 学习与复现】-- 深度学习系列 -- NFM
  19. 获取Android设备的唯一识别码|设备号|序号|UUI
  20. Tracup Talk:如何制作项目管理的甘特图?

热门文章

  1. mysql -f --force_mysqldump备份MYSQL数据库的参数详细说明
  2. 硬盘分区表知识—详解硬盘MBR
  3. (转) MCU实战经验---多种的按键处理
  4. fastdfs中浏览器访问获取不到文件_SpringBoot 2.0 开发案例之整合FastDFS分布式文件系统...
  5. STM32F103mini教程学习总结与心得(五)---->通用定时器
  6. python做病毒传播的空间数据_利用4行Python代码监测每一行程序的运行时间和空间消耗...
  7. three.js 后期处理,物体高亮
  8. JavaScript常用数组操作方法,包含ES6方法
  9. PCL之多可视化窗口
  10. 软件工程java向量相似度计算_向量的相似度计算常用方法9个