[原][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云平台上直接提供的服务器数字证书.您可以在阿里云.腾讯云等平台 ...
随机推荐
- 机器学习理论基础学习4--- SVM(基于结构风险最小化)
一.什么是SVM? SVM(Support Vector Machine)又称为支持向量机,是一种二分类的模型.当然如果进行修改之后也是可以用于多类别问题的分类.支持向量机可以分为线性和非线性两大类. ...
- VMware Coding Challenge: The Heist
类似BackpackII问题 static int maximize_loot(int[] gold, int[] silver) { int[][] res = new int[gold.lengt ...
- VMware coding Challenge:Date of Weekday
这道题再次证明了这种细节的题目,画个图容易搞清楚 import java.util.Scanner; public class Solution2 { static int DateOfWeekday ...
- Liferay中request
在liferay中的请求分为renderRequest和actionRequest这两种请求的方式,portletRequest的子类有三个1renderRequest,2EventRequest3C ...
- wcf 服务器无法处理请求由于内部错误
The server was unable to process the request due to an internal error. For more information about t ...
- Java(1-15)
1.方法参数是引用类型,传递的是内存地址!2.方法的重载特性:在同一个类中,允许方法同名,只要方法的参数列表不同即可!3.Stirng特殊在如果静态数据区中存在,那么不创建新的对象,而是指向这个对象. ...
- Windows下使用MakeFile(Mingw)文件
下面是我基于<C++GUI QT4编程(第二版)> 2.3节快速设计对话框编写例子地址: https://files.cnblogs.com/files/senior-engineer/g ...
- 浏览器内核、排版引擎、js引擎
[定义] 浏览器最重要或者说核心的部分是“Rendering Engine”,可大概译为“渲染引擎”,不过我们一般习惯将之称为“浏览器内核”.负责对网页语法的解释(如标准通用标记语 言下的一个应用HT ...
- JavaScript 读取修改元素 及 伸拉门案例
JavaScript 读取修改元素 及 伸拉门案例 版权声明:未经授权,严禁转载! 读取 / 修改元素 - 读取修改元素内容 - 读取修改元素属性 - 读取修改元素样式 元素的内容 读取或修改元素节点 ...
- 数据库 - SQLite3 中的数据类型
------------------------------ 安装 Sqlite3 和 数据库查看工具: sudo apt-get install sqlite3 sudo apt-get insta ...