因为对于globalmap不熟悉,不怎么怎么修改高程,好像也没有这功能。

干脆自己手动修改了高程图tiff了

由于自身一直使用osg的 自己使用了osgDB直接读取tiff,修改后保存的。

同事小周一直研究gdal,她使用了gdal库直接改的,事实证明在专业gis处理上还是gdal更合适,现在把两种方式都总结一下:

第一种:通过osgDB修改tiff

 #include <osg/Image>
#include <osgViewer/Viewer>
#include <osgEarth/Registry>
#include <osgEarth/ImageToHeightFieldConverter>
#include <osgEarth/ImageUtils>
#include <osgEarth/FileUtils>
#include <osgEarth/MapFrame>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <math.h>
using namespace osgEarth; void floating(osg::HeightField* &hf)
{
float floatingData = 179.0;
float fBegin = 140.0;
for (unsigned col = ; col < hf->getNumColumns(); ++col)
{
for (unsigned row = ; row < hf->getNumRows(); ++row)
{
float height = hf->getHeight(col, row);
if (height < fBegin)
{
hf->setHeight(col, row, floatingData);
}
}
}
} void seaboard(osg::HeightField* &hf)
{ float fBegin = 0.1;
//float fEnd = 0.000001;
float fLowestValue = 1000.0;
int fWide = 100.0;
int *fFlag = new int[hf->getNumColumns()*hf->getNumRows()]; for (unsigned col = ; col < hf->getNumColumns(); ++col)
{
for (unsigned row = ; row < hf->getNumRows(); ++row)
{
fFlag[col*hf->getNumRows() + row] = ;
float height = hf->getHeight(col, row);
if (height < fBegin)
{
fFlag[col*hf->getNumRows() + row] = ;
hf->setHeight(col, row, - fLowestValue); /*简单的计算
float newh = -1000.0;
if(height > 0.00001)
newh = 0.1 - (0.1 - height)/ (0.1-0.00001)*1000.0;
hf->setHeight(col, row, newh);*/
}
}
} for (int i = ; i < hf->getNumColumns()*hf->getNumRows(); i++)
{
if (fFlag[i] == )//如果这值在海面以下
{
bool isNearSide = false;
int nowX = i / hf->getNumRows();
int nowY = i%hf->getNumRows();
for (int j = ; j <= fWide; j++)
{
//从离此值最近的值开始找附近的岸边,往外延伸
//向东南西北四个方向找,没层都遍历一圈
for (int x = ; x <= j; x++)
{
//如果找到有岸边
int fDifValueX = x;
int fDifValueY = j - x;
int realX = nowX - fDifValueX;
if (realX > )
{
int realY = nowY - fDifValueY;
if (realY > )
{
if (fFlag[realX*hf->getNumRows() + realY] == )//如果是岸边
isNearSide = true;
}
realY = nowY + fDifValueY;
if (realY < hf->getNumRows())
{
if (fFlag[realX*hf->getNumRows() + realY] == )//如果是岸边
isNearSide = true;
}
} realX = nowX + fDifValueX;
if (realX < hf->getNumColumns())
{
int realY = nowY - fDifValueY;
if (realY > )
{
if (fFlag[realX*hf->getNumRows() + realY] == )//如果是岸边
isNearSide = true;
}
realY = nowY + fDifValueY;
if (realY < hf->getNumRows())
{
if (fFlag[realX*hf->getNumRows() + realY] == )//如果是岸边
isNearSide = true;
}
}
} //查找这个范围内是否有值,如果有值则用此值
if (isNearSide)
{
float fRealHeight = fBegin - j * fLowestValue / fWide;
hf->setHeight((i / hf->getNumRows()), (i % hf->getNumRows()), fRealHeight);
break;//退出当前寻找的延伸
}
}
}
} delete[]fFlag;
} int main(int argc, char** argv)
{ ReadResult result;
osg::ref_ptr<osgDB::ReaderWriter> reader = osgDB::Registry::instance()->getReaderWriterForExtension("tif");
std::string name("D:\\srtm_19_032.tif");
osgDB::ReaderWriter::Options* opt= NULL;
osgDB::ReaderWriter::ReadResult rr = reader->readImage(name, opt); if (rr.validImage())
{
result = ReadResult(rr.takeImage());
result.getImage()->setName("srtm_19_03.tif");
} if (result.succeeded())
{
result.getObject();
result.metadata();
osg::ref_ptr<osg::Image> image = result.getImage(); osgEarth::ImageToHeightFieldConverter conv;
osg::HeightField* hf = conv.convert(image.get()); //seaboard(hf);
floating(hf); osg::Image* newimage = conv.convert(hf);
std::string nameofnew("D:\\srtm_19_03.tif");
reader->writeImage(*newimage, nameofnew); } return ;
}

第二种:通过gdal库修改tiff

getImgInfo.h

 #include "gdal.h"
#include "gdal_priv.h"
#include <string>
using namespace std; int getImgInfo(string szInFile, GDALDataset **poDataset, int *nbands, double **geoTrans, int *width, int *height, GDALDataType *gdt, const char** projRef, GDALRasterBand *** poBand)
{
GDALAllRegister(); GDALDataset *poDatasetTmp = *poDataset;
poDatasetTmp = (GDALDataset*)GDALOpen(szInFile.c_str(), GA_ReadOnly); int widthTmp = *width, heightTmp = *height, nbandsTmp = *nbands;
widthTmp = poDatasetTmp->GetRasterXSize();
heightTmp = poDatasetTmp->GetRasterYSize();
nbandsTmp = poDatasetTmp->GetRasterCount(); GDALDataType gdtTmp = *gdt;
gdtTmp = poDatasetTmp->GetRasterBand()->GetRasterDataType(); double *geoTransTmp = *geoTrans;
geoTransTmp = new double[];
poDatasetTmp->GetGeoTransform(geoTransTmp);//获取地理坐标信息,地理坐标信息是一个含6个double型数据的数组, const char* projRefTmp = *projRef;
projRefTmp = poDatasetTmp->GetProjectionRef(); //获取投影信息 GDALRasterBand ** poBandTmp = *poBand;
poBandTmp = new GDALRasterBand *[nbandsTmp];
if (poBand == NULL)
{
cout << "GDALRasterBand ** poBand = new GDALRasterBand *[nBands]; failed!" << endl;
}
for (int i = ; i < nbandsTmp; i++)
{
poBandTmp[i] = poDatasetTmp->GetRasterBand(i + );
} *poDataset = poDatasetTmp;
*nbands = nbandsTmp;
*geoTrans = geoTransTmp;
*width = widthTmp;
*height = heightTmp;
*gdt = gdtTmp;
*projRef = projRefTmp;
*poBand = poBandTmp; return ;
}

main.cpp

 #include "gdal.h"
#include "gdal_priv.h"
#include <iostream>
#include <string> #include "getImgInfo.h"
using namespace std; typedef unsigned short UINT; //(0,65535) int _tmain(int argc, _TCHAR* argv[])
{
int ret=;
GDALAllRegister(); string szInFile="F:\\IMG_PROCESS\\srtm_19_03.tif"; double *adfGeoTransform;
GDALDataType gdt;
GDALDataset *poDataset;
int Width, Height, nBands;
GDALRasterBand ** poBand;
const char* projRef;
ret=getImgInfo(szInFile,&poDataset,&nBands,&adfGeoTransform,&Width,&Height ,&gdt,&projRef, &poBand); UINT **poBandBlock = new UINT*[nBands];
if (poBandBlock==NULL)
{
cout<<"UINT **poBandBlock = new UINT *[outBand]; failed!"<<endl;
system("pause");
return -;
}
UINT **poBandBlock_out = new UINT *[nBands];
if (poBandBlock_out==NULL)
{
cout<<"UINT **poBandBlock_out = new byte *[outBand]; failed!"<<endl;
system("pause");
return -;
} int xHei=; //一次处理xHei=400行数据 分块处理
int timePerxH=Height/xHei+; GDALDriver *poDriver=NULL;
poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); string output_file="F:\\IMG_PROCESS\\srtm_19_03_tmp.tif"; GDALDataset *BiomassDataset;
BiomassDataset=poDriver->Create(output_file.c_str(),Width,Height,nBands,gdt, NULL); int tmp=;//防止无符号数越界 //开始分块处理////
for (int i=;i<timePerxH - ;i++) //i表示分块处理需处理次数计数
{
for (int j=;j<nBands;j++)
{
poBandBlock[j] = new UINT[Width*xHei];
if (poBandBlock[j]==NULL)
{
cout<<"poBandBlock[j] = new UINT[Width*xHei]; failed!"<<endl;
system("pause");
return -;
}
poBandBlock_out[j] = new UINT[Width*xHei];
if (poBandBlock_out[j]==NULL)
{
cout<<"poBandBlock_out[j] = new byte[Width*xHei]; failed!"<<endl;
system("pause");
return -;
}
}
for (int k=; k<nBands; k++ )
{
poBand[k]->RasterIO(GF_Read, ,i*xHei,Width,xHei, poBandBlock[k], Width,xHei, gdt, , );
} //poBandBlock像素操作////
for (int i=;i<nBands;i++)
{
for (int j=;j<xHei;j++)
{
for (int k=;k<Width;k++)
{
if (poBandBlock[i][j*Width+k]==)
{
poBandBlock_out[i][j*Width+k]=;
}
else if (poBandBlock[i][j*Width+k]>=)
{
poBandBlock_out[i][j*Width+k]=;
}
else
{
poBandBlock_out[i][j*Width+k] = poBandBlock[i][j*Width+k];
}
}
}
}
for(int k = ; k < nBands; k++)
{
BiomassDataset->GetRasterBand (k+)->RasterIO(GF_Write,,xHei*i,Width,xHei,poBandBlock_out[k],Width,xHei,gdt,,);
} for (int j=;j<nBands;j++)
{
delete []poBandBlock[j];
poBandBlock[j]=NULL; delete poBandBlock_out[j];
poBandBlock_out[j]=NULL;
}
} //////剩余行数处理////
int foreH=(timePerxH-)*xHei;
int leftH=Height-foreH;
for (int j=;j<nBands;j++)
{
poBandBlock[j] = new UINT[Width*leftH];
if (poBandBlock[j]==NULL)
{
cout<<"poBandBlock[j] = new UINT[Width*leftH]; failed!"<<endl;
system("pause");
return -;
}
poBandBlock_out[j] = new UINT[Width*leftH];
if (poBandBlock_out[j]==NULL)
{
cout<<"poBandBlock_out[j] = new byte[Width*leftH]; failed!"<<endl;
system("pause");
return -;
}
}
for (int k=; k<nBands; k++ )
{
poBand[k]->RasterIO(GF_Read, ,foreH,Width,leftH, poBandBlock[k], Width,leftH, gdt, , );
}
//poBandBlock像素操作////
for (int i=;i<nBands;i++)
{
for (int j=;j<leftH;j++)
{
for (int k=;k<Width;k++)
{
if (poBandBlock[i][j*Width+k]==)
{
poBandBlock_out[i][j*Width+k]=;
}
else if (poBandBlock[i][j*Width+k]>=)
{
poBandBlock_out[i][j*Width+k]=;
}
else
{
poBandBlock_out[i][j*Width+k]=poBandBlock[i][j*Width+k];
}
}
}
}
for(int k = ; k < nBands; k++)
{
BiomassDataset->GetRasterBand(k+)->RasterIO(GF_Write,,foreH,Width,leftH,poBandBlock_out[k],Width,leftH,gdt,,);
}
for (int j=;j<nBands;j++)
{
delete poBandBlock[j];
poBandBlock[j]=NULL; delete poBandBlock_out[j];
poBandBlock_out[j]=NULL;
} ////////对指定的某个区域数据重新赋值//////////////////////////////////////////////////////////////////
for (int j = ; j < nBands; j++)
{
poBandBlock[j] = new UINT[ * ];
if (poBandBlock[j] == NULL)
{
cout << "poBandBlock[j] = new UINT[Width*leftH]; failed!" << endl;
system("pause");
return -;
}
poBandBlock_out[j] = new UINT[ * ];
if (poBandBlock_out[j] == NULL)
{
cout << "poBandBlock_out[j] = new byte[Width*leftH]; failed!" << endl;
system("pause");
return -;
}
}
for (int k = ; k < nBands; k++)
{
poBand[k]->RasterIO(GF_Read, , , , , poBandBlock[k], , , gdt, , );
}
//poBandBlock像素操作//
for (int i = ; i < nBands; i++)
{
for (int j = ; j < ; j++)
{
for (int k = ; k < ; k++)
{
poBandBlock_out[i][j* + k] = ;
}
}
}
for (int k = ; k < nBands; k++)
{
BiomassDataset->GetRasterBand(k + )->RasterIO(GF_Write, , , , , poBandBlock_out[k], , , gdt, , );
}
for (int j = ; j < nBands; j++)
{
delete poBandBlock[j];
poBandBlock[j] = NULL; delete poBandBlock_out[j];
poBandBlock_out[j] = NULL;
}
////////////////////////////////////////////////////////////////////////// delete poBandBlock;
poBandBlock=NULL;
delete poBandBlock_out;
poBandBlock_out=NULL; BiomassDataset->SetGeoTransform(adfGeoTransform);
BiomassDataset->SetProjection(projRef);
system("pause"); }

[原][osg][gdal]两种方式修改tiff高程的更多相关文章

  1. Win10秘笈:两种方式修改网卡物理地址(MAC)

    每台能够上网的电脑都有网卡,不管是有线还是无线,网卡本身都得有物理地址,也就是MAC(Media Access Control 或 Medium Access Control)地址.这个地址理论上是固 ...

  2. 云服务器 ECS Linux 服务器修改时区的两种方式

    在云服务器 ECS Linux 系统中,以 Centos6.5 为例,可以通过如下两种方式,修改系统时区: 可以使用命令 tzselect,修改时区.操作示例: [root@localhost ~]# ...

  3. linux中添加一个用户到指定用户组的两种方式,修改一个用户到指定用户组的一种方式

    添加一个用户到指定用户组: gpasswd –a 用户名 组名usermod –G 组名 用户名 //第一种:gpasswd –a 用户名 组名 [root@localhost ~]# id user ...

  4. mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样

    Mybatis批量更新数据 mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样 mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样 mybatis批 ...

  5. TreeMap集合根据指定元素,进行删除和修改的两种方式实现及bug梳理

    TreeMap根据key中的指定元素进行删除修改的两种方式实现及注意事项: 方式一:利用增强for进行删除和修改 总结:逻辑简单,但是局限性太强,如果排序规则是从小到大进行排序的,则该方法不能进行删除 ...

  6. 传递引用类型参数的两种方式(转自 MSDN)

    引用类型的变量不直接包含其数据:它包含的是对其数据的引用.当通过值传递引用类型的参数时,有可能更改引用所指向的数据,如某类成员的值(更改属性的值),但是无法更改引用本身的值:也就是说,不能使用相同的引 ...

  7. 将html页改成jsp的两种方式

    将html页改成jsp的两种方式 作者: 字体:[增加 减小] 类型:转载 时间:2013-08-13 将html页改成jsp有两种方法,第一种是直接修改html文件,另一种是新建jsp文件.下面为大 ...

  8. java 的对象拷贝(有深浅拷贝两种方式,深拷贝实现的两种方式(逐层实现cloneable接口,序列化的方式来实现))

    Java提高篇--对象克隆(复制)(转自:http://www.cnblogs.com/Qian123/p/5710533.html#_label0)   阅读目录 为什么要克隆? 如何实现克隆 浅克 ...

  9. 第二节:SSL证书的申请、配置(IIS通用)及跳转Https请求的两种方式

    一. 相关概念介绍 1. SSL证书服务 SSL证书服务由"服务商"联合多家国内外数字证书管理和颁发的权威机构.在xx云平台上直接提供的服务器数字证书.您可以在阿里云.腾讯云等平台 ...

随机推荐

  1. 安装PHP及Memcache扩展

    安装PHP及Memcache扩展 地址:http://blog.csdn.net/poechant/article/details/6802312   1. 下载 (1)libevent 官方网页:h ...

  2. win10安装激活与关闭自动更新

    1.安装时即使选择了不保留任何文件,也不会删除掉非c盘里的东西 2.安装后需要执行KMS10_Crack2激活下 3.关闭自动更新. 在服务中禁用 https://zhidao.baidu.com/q ...

  3. String源码详解

    一.基本概念. 1.继承实现关系.因为被final修饰,因此是不可继承的String类,避免被他人继承后修改.实现了三个接口.可序列.可比较,有序.几个String兄弟类 2.本质就是字符数组,同时, ...

  4. SV搭建验证环境

    1)首先定义纯虚类Sv_object,主要实现下边两个function: 定义local static 变量nextobjectID; 虚方法 virtual function void copy(S ...

  5. SV中的task和function

    SV中class的properties和methods默认都是public的,但是可以声明为local和protected. 一个properties声明为local类型的,则只在该class中的me ...

  6. MySQL从删库到跑路(六)——SQL插入、更新、删除操作

    作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.插入数据 1.为表的所有字段插入数据 使用基本的INSERT语句插入数据要求指定表名称和插入到新记录的值. IN ...

  7. mysql索引使用策略及优化

    原文地址:http://blog.codinglabs.org/articles/theory-of-mysql-index.html 索引使用策略及优化 MySQL的优化主要分为结构优化(Schem ...

  8. 拉取远程仓库到本地错误The authenticity of host 'github.com (13.229.188.59)' can't be established.

    1.个人在github上面创建了仓库,通过本地的git拉取远程仓库到本地报错信息如下: 这是因为Git使用SSH连接,而SSH第一次连接需要验证GitHub服务器的Key.确认GitHub的Key的指 ...

  9. python之路----面向对象的继承特性

    继承 什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 python中类的继承分为:单继承和多继承 class ...

  10. linux不常用但很有用的命令(持续完善)

    Linux登录后设置提示信息: /etc/issue 本地端登录前显示信息文件 /etc/issue.net 网络端登录前显示信息文件 /etc/motd 登陆后显示信息文件 可以添加以下几个常用选项 ...