[原][osg][gdal]两种方式修改tiff高程
因为对于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高程的更多相关文章
- Win10秘笈:两种方式修改网卡物理地址(MAC)
每台能够上网的电脑都有网卡,不管是有线还是无线,网卡本身都得有物理地址,也就是MAC(Media Access Control 或 Medium Access Control)地址.这个地址理论上是固 ...
- 云服务器 ECS Linux 服务器修改时区的两种方式
在云服务器 ECS Linux 系统中,以 Centos6.5 为例,可以通过如下两种方式,修改系统时区: 可以使用命令 tzselect,修改时区.操作示例: [root@localhost ~]# ...
- linux中添加一个用户到指定用户组的两种方式,修改一个用户到指定用户组的一种方式
添加一个用户到指定用户组: gpasswd –a 用户名 组名usermod –G 组名 用户名 //第一种:gpasswd –a 用户名 组名 [root@localhost ~]# id user ...
- mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样
Mybatis批量更新数据 mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样 mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样 mybatis批 ...
- TreeMap集合根据指定元素,进行删除和修改的两种方式实现及bug梳理
TreeMap根据key中的指定元素进行删除修改的两种方式实现及注意事项: 方式一:利用增强for进行删除和修改 总结:逻辑简单,但是局限性太强,如果排序规则是从小到大进行排序的,则该方法不能进行删除 ...
- 传递引用类型参数的两种方式(转自 MSDN)
引用类型的变量不直接包含其数据:它包含的是对其数据的引用.当通过值传递引用类型的参数时,有可能更改引用所指向的数据,如某类成员的值(更改属性的值),但是无法更改引用本身的值:也就是说,不能使用相同的引 ...
- 将html页改成jsp的两种方式
将html页改成jsp的两种方式 作者: 字体:[增加 减小] 类型:转载 时间:2013-08-13 将html页改成jsp有两种方法,第一种是直接修改html文件,另一种是新建jsp文件.下面为大 ...
- java 的对象拷贝(有深浅拷贝两种方式,深拷贝实现的两种方式(逐层实现cloneable接口,序列化的方式来实现))
Java提高篇--对象克隆(复制)(转自:http://www.cnblogs.com/Qian123/p/5710533.html#_label0) 阅读目录 为什么要克隆? 如何实现克隆 浅克 ...
- 第二节:SSL证书的申请、配置(IIS通用)及跳转Https请求的两种方式
一. 相关概念介绍 1. SSL证书服务 SSL证书服务由"服务商"联合多家国内外数字证书管理和颁发的权威机构.在xx云平台上直接提供的服务器数字证书.您可以在阿里云.腾讯云等平台 ...
随机推荐
- python+requests接口自动化完整项目设计源码(一)
原文地址https://www.cnblogs.com/yoyoketang/tag/python接口自动化/ 原文地址https://www.cnblogs.com/yoyoketang/ 原文地址 ...
- Azkaban 简介
本文简单介绍一下Azkaban及其特点.azkaban是一个开源的任务调度系统,用于负责任务的调度运行(如数据仓库调度),用以替代linux中的crontab. 一.Azkaban是什么? 1.1 A ...
- 生产者消费者模型——wait/notify/notifyAll使用
告警系统架构如下 1. 数据处理系统处理完原始数据并入库后,发送消息到kafka系统: 2. 告警生产者从kafka系统查询消息存入告警消息队列: 3. 告警消费者从告警消息队列查询消息进行处理. 这 ...
- linux基础命令---whereis
whereis 查找命令的位置,包括执行文件.源代码.手册文件. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. 1.语法 ...
- ThinkPHP问题收集:模板中使用U方法时无法嵌套大括号,For标签,插入数据,新增的表字段缓存问题
ThinkPHP模板中使用U方法时无法嵌套大括号需要在control里面用U方法赋值给变量传到模版如:{:U('/Blog/comment/',array('id'=>$id)}$comment ...
- Python中文件的读写操作的几种方法
对文件的操作,步骤为:打开一个文件-->读取/写入内容-->保存文件 文件读写的3中模式 # 1.w 写模式,它是不能读的,如果用w模式打开一个已经存在的文件,会清空以前的文件内容,重新写 ...
- 虚拟机中安装mac系统
虚拟机安装就很简单了,傻瓜式安装,一直点击下一步就行,这里就不多说了. 所需要的配置: 虚拟机下载地址:链接:http://pan.baidu.com/s/1i45wXRf 密码:7c4x mac补丁 ...
- (一)github之基础概念篇
1.github: 一项为开发者提供git仓库的托管服务, 开发者间共享代码的场所.github上公开的软件源代码全都由git进行管理. 2.git: 开发者将源代码存入名为git仓库的资料库中,而g ...
- Centos6版本使用yum报错 Loaded plugins: fastestmirror, refresh-packagekit, security Loading mirror speeds from cached hostfi Setting up Install Process No package gcc available. Error: Nothing to do
在使用Centos6版本yum时报错 Loaded plugins: fastestmirror, refresh-packagekit, securityLoading mirror speeds ...
- 20145104张家明 《Java程序设计》第9周学习总结
20145104张家明 <Java程序设计>第9周学习总结 教材学习内容总结 第16章 -撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找. -JDBC目的:让Java ...