www.pudn.com > dstile-0.2.rar > Tiler.cpp
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #include #include "syskit.h" #include "giskit.h" #include #include #include #include #include #include Tiler::Tiler() : m_needCloseSrc(false), m_needEndTiling(false), m_tileAccessor(0), m_tileProcessor(0), m_cSTrans(0), m_warper(0), m_overviews(0), m_tile(0), m_memDrv(0), m_src(0), m_srcFileName(), m_srcSRS(), m_vSrcGT(false), m_srcGT(), m_dstSRS(), m_ex0(0.0), m_ey0(0.0), m_ex1(0.0), m_ey1(0.0), m_tsx(0), m_tsy(0), m_tBands(3), m_tDataType(GDT_Byte), m_l0tx(1), m_l0ty(1) { m_memDrv = GetGDALDriverManager()->GetDriverByName("MEM"); } Tiler::~Tiler() { if (m_needEndTiling) EndTiling(); if (m_needCloseSrc) CloseSrc(); } void Tiler::OpenSrc(const string& srcFileName) { if (m_needCloseSrc) CloseSrc(); m_needCloseSrc = true; m_srcFileName = srcFileName; m_src = reinterpret_cast(GDALOpen(srcFileName.c_str(), GA_ReadOnly)); if (!m_src) throw Exception("Tiler::OpenSrc failed: unable to open '%s'.", srcFileName.c_str()); if (m_src->GetProjectionRef()) m_srcSRS = m_src->GetProjectionRef(); if (m_src->GetGeoTransform(m_srcGT.m_mat) == CE_None) m_vSrcGT = true; } void Tiler::CloseSrc() { if (m_src) { GDALClose(m_src); m_src = 0; } m_srcFileName.clear(); m_needCloseSrc = false; } void Tiler::BeginTiling() { m_needEndTiling = true; m_cSTrans->Create(m_srcSRS, m_dstSRS, 0.2); m_cSTrans->SetSrcGT(m_srcGT); m_tile = m_memDrv->Create("", m_tsx, m_tsy, m_tBands, m_tDataType, 0); if (!m_tile) throw Exception("Tiler::BeginTiling failed: unable to create in-memory image."); m_warper->Create(m_src, m_tile, *m_cSTrans); } void Tiler::EndTiling() { if (m_needEndTiling) { m_warper->Destroy(); if (m_tile) { delete m_tile; m_tile = 0; } m_cSTrans->Destroy(); m_needEndTiling = false; } } double Tiler::EstimateLevel() { GeoT gt; int sx, sy; double lx, ly; m_cSTrans->SetDstGT(GeoT::Identity()); GDALSuggestedWarpOutput(m_src, m_cSTrans->GetCSTransFunc(), m_cSTrans->GetCSTransArg(), gt.m_mat, &sx, &sy); lx = log(fabs(gt.m_mat[1] * m_tsx * m_l0tx / (m_ex1 - m_ex0))) / log(0.5); ly = log(fabs(gt.m_mat[5] * m_tsy * m_l0ty / (m_ey1 - m_ey0))) / log(0.5); return (lx + ly) * 0.5; } void Tiler::Tile(int level) { GeoT gt; int sx, sy; int x0, y0, x1, y1; double rx, ry; int x, y; int n, nn; double a, b; GDALDataset *prevTile; FileLock fl; if (level < 0) level = 0; m_cSTrans->SetDstGT(GeoT::Identity()); GDALSuggestedWarpOutput(m_src, m_cSTrans->GetCSTransFunc(), m_cSTrans->GetCSTransArg(), gt.m_mat, &sx, &sy); rx = (m_ex1 - m_ex0) / (m_l0tx * pow(2.0, level)); ry = (m_ey1 - m_ey0) / (m_l0ty * pow(2.0, level)); x0 = static_cast(floor((gt.m_mat[0] - m_ex0) / rx)); y0 = static_cast(floor((gt.m_mat[3] - m_ey0) / ry)); x1 = static_cast(ceil((gt.m_mat[0] + gt.m_mat[1] * sx - m_ex0) / rx)); y1 = static_cast(ceil((gt.m_mat[3] + gt.m_mat[5] * sy - m_ey0) / ry)); nn = (x1 - x0) * (y1 - y0); printf("%s", m_srcFileName.c_str()); n = 0; GDALTermProgress(0.0, "", 0); for (y = y0; y < y1; ++y) for (x = x0; x < x1; ++x) { ++n; GDALTermProgress((1.0 * n) / nn, "", 0); for (int i = 1; i <= m_tBands; ++i) m_tile->GetRasterBand(i)->Fill(0.0); m_cSTrans->SetDstGT(GeoT(m_ex0 + x * rx, m_ey0 + y * ry, rx / m_tsx, ry / m_tsy)); m_warper->ChunkAndWarpImage(0, 0, m_tsx, m_tsy); if (!m_tileProcessor->IsNull(m_tile)) { string loc = m_tileAccessor->LocateTile(level, x, y); fl.Open(loc); fl.LockExclusive(); if (fl.GetSize()) prevTile = m_tileAccessor->Read(level, x, y); else prevTile = 0; try { if (prevTile) m_tileProcessor->Combine(m_tile, prevTile, m_tile); m_tileAccessor->Write(level, x, y, m_tile); fl.Unlock(); fl.Close(); } catch (...) { if (prevTile) delete prevTile; throw; } if (prevTile) delete prevTile; if (m_overviews) m_overviews->Insert(level, x, y); } } }