www.pudn.com > dstile-0.2.rar > Overviews.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 "exceptions.h" #include "syskit.h" #include "giskit.h" #include "TileAccessor.h" #include "TileProcessor.h" #include "Overviews.h" Overviews::Overviews() : m_memDrv(0) { m_memDrv = GetGDALDriverManager()->GetDriverByName("MEM"); } Overviews::~Overviews() { for (map::iterator it = m_trees.begin(); it != m_trees.end(); ++it) delete it->second; } void Overviews::Insert(int l, int x, int y) { int idx = ((y >> l) << 16) + (x >> l); TileTree *p = m_trees[idx]; if (!p) { p = new TileTree(); m_trees[idx] = p; } p->Insert(l, x % (1 << l), y % (1 << l)); } void Overviews::BuildOverviewsR(TileTree::Node *p, int l, int x, int y) { ++m_curCount; if (p->m_child[0]) BuildOverviewsR(p->m_child[0], l + 1, (x << 1), (y << 1)); if (p->m_child[1]) BuildOverviewsR(p->m_child[1], l + 1, (x << 1) + 1, (y << 1)); if (p->m_child[2]) BuildOverviewsR(p->m_child[2], l + 1, (x << 1), (y << 1) + 1); if (p->m_child[3]) BuildOverviewsR(p->m_child[3], l + 1, (x << 1) + 1, (y << 1) + 1); if (p->m_child[0] || p->m_child[1] || p->m_child[2] || p->m_child[3]) { GDALDataset *out = 0, *op[4]; FileLock fl; int xx, yy; int sx = 0, sy = 0; int bands; GDALDataType dataType; for (int i = 0; i < 4; ++i) op[i] = 0; try { for (int i = 0; i < 4; ++i) { xx = i & 1; yy = (i >> 1) & 1; string loc = m_tileAccessor->LocateTile(l + 1, (x << 1) + (i & 1), (y << 1) + ((i >> 1) & 1)); if (!access(loc.c_str(), R_OK)) { fl.Open(m_tileAccessor->LocateTile(l + 1, (x << 1) + (i & 1), (y << 1) + ((i >> 1) & 1))); fl.LockExclusive(); if (fl.GetSize()) { op[i] = m_tileAccessor->Read(l + 1, (x << 1) + (i & 1), (y << 1) + ((i >> 1) & 1), true); if (!op[i]) continue; sx = op[i]->GetRasterXSize(); sy = op[i]->GetRasterYSize(); bands = op[i]->GetRasterCount(); dataType = op[i]->GetRasterBand(1)->GetRasterDataType(); } fl.Unlock(); fl.Close(); } } if (!sx || !sy) throw Exception("Overviews::BuildOverviews failed: no files where they should be ..."); out = m_memDrv->Create("", sx, sy, bands, dataType, 0); if (!out) throw Exception("Overviews::BuildOverviews failed: unable to create in-memory image."); m_tileProcessor->Subsample2x2(out, op[0], op[1], op[2], op[3]); fl.Open(m_tileAccessor->LocateTile(l, x, y)); fl.LockExclusive(); m_tileAccessor->Write(l, x, y, out); fl.Unlock(); fl.Close(); } catch (...) { for (int i = 0; i < 4; ++i) if (op[i]) delete op[i]; if (out) delete out; throw; } for (int i = 0; i < 4; ++i) if (op[i]) delete op[i]; if (out) delete out; GDALTermProgress((1.0 * m_curCount) / m_count, "", 0); } } void Overviews::BuildOverviews() { printf("Building overviews"); fflush(stdout); GDALTermProgress(0.0, "", 0); m_count = 0; m_curCount = 0; for (map::iterator it = m_trees.begin(); it != m_trees.end(); ++it) m_count += it->second->m_count; for (map::iterator it = m_trees.begin(); it != m_trees.end(); ++it) { BuildOverviewsR(it->second->m_root, 0, it->first & 0xFFFF, (it->first >> 16) & 0xFFFF); } }