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);
    }
}