osgEarth 2.1.1
|
Public Member Functions | |
WorldWindSource (const TileSourceOptions &options) | |
void | initialize (const std::string &referenceURI, const Profile *overrideProfile) |
osg::HeightField * | createHeightFieldFromBil (char *buf, int buflength) |
osg::Image * | createImage (const TileKey &key, ProgressCallback *progress) |
osg::HeightField * | createHeightField (const TileKey &key, ProgressCallback *progress) |
std::string | createCachePath (const TileKey &key) const |
std::string | createCacheName (const TileKey &key) const |
std::string | createURI (const TileKey &key) const |
virtual int | getPixelsPerTile () const |
virtual std::string | getExtension () const |
Private Attributes | |
WorldWindOptions | _options |
Definition at line 54 of file ReaderWriterWorldWind.cpp.
WorldWindSource::WorldWindSource | ( | const TileSourceOptions & | options | ) | [inline] |
Definition at line 57 of file ReaderWriterWorldWind.cpp.
: TileSource( options ) { _options = options; }
std::string WorldWindSource::createCacheName | ( | const TileKey & | key | ) | const [inline] |
Definition at line 266 of file ReaderWriterWorldWind.cpp.
{ unsigned int x, y; key.getTileXY(x, y); unsigned int lod = key.getLevelOfDetail(); // flip the y based on level int flippedy = ((9 * powf((int)2,(int)lod)) - 1) - y; //printf("Key %i, %i, %i\n", lod,x,flippedy); std::stringstream buf; buf << "" << std::setw(4) << std::setfill('0') << x << "_" << std::setw(4) << std::setfill('0') << flippedy; std::string bufStr; bufStr = buf.str(); return bufStr; }
std::string WorldWindSource::createCachePath | ( | const TileKey & | key | ) | const [inline] |
Definition at line 251 of file ReaderWriterWorldWind.cpp.
{ unsigned int x, y; key.getTileXY(x, y); unsigned int lod = key.getLevelOfDetail(); std::stringstream buf; buf << "" << lod << "/" << std::setw(4) << std::setfill('0') << x; std::string bufStr; bufStr = buf.str(); return bufStr; }
osg::HeightField* WorldWindSource::createHeightField | ( | const TileKey & | key, |
ProgressCallback * | progress | ||
) | [inline, virtual] |
Creates a heightfield for the given TileKey The returned object is new and is the responsibility of the caller.
Reimplemented from osgEarth::TileSource.
Definition at line 104 of file ReaderWriterWorldWind.cpp.
{ if ( *_options.maxLOD() <= key.getLevelOfDetail()) return NULL; if ( !_options.elevationCachePath().isSet() ) return NULL; osg::HeightField *hf = NULL; std::string cachefilepath = *_options.elevationCachePath() + "/" + createCachePath(key); std::string cachefilename = createCacheName(key) + ".bil"; std::string fullcachefilename = cachefilepath + "/" + cachefilename; OE_DEBUG << LC << "Cached name " << fullcachefilename << std::endl; if (osgDB::fileExists(fullcachefilename)) { // read file std::ifstream fin; fin.open(fullcachefilename.c_str(), std::ios::in | std::ios::binary); if (!fin) { OE_WARN << LC << "Coud not open elevation cache " << fullcachefilename << ", maybe a permissions problem" << std::endl; _options.elevationCachePath().unset(); return NULL; } int fullsize = 150*150*2; char *buf = new char[fullsize]; OE_DEBUG << LC << "Loading from cache " << fullcachefilename << std::endl; if ( !fin.read(buf, fullsize)) { OE_WARN << LC << "Coud not read from elevation cache " << fullcachefilename << ", file may be corrupt" << std::endl; delete[] buf; fin.close(); _options.elevationCachePath().unset(); return NULL; } hf = createHeightFieldFromBil((char*)buf,fullsize); delete[] buf; fin.close(); } else // cached BIL file doesn't exist, try to download and cache it. { // download file HTTPResponse out_response; std::string URI = createURI(key); OE_DEBUG << "Requesting " << URI << std::endl; out_response = HTTPClient::get( URI, 0L, progress ); if ( !out_response.isOK() ) { OE_NOTICE << "No Response received for " << URI << std::endl; return NULL; } // store downloaded part as a zip file // Useful to store a local copy as the same file is requested many times unsigned int part_num = out_response.getNumParts() > 1? 1 : 0; std::string zipfilename; out_response.getPartHeader(part_num, zipfilename); std::istream& input_stream = out_response.getPartStream( part_num ); if ( !osgDB::fileExists(cachefilepath) ) { osgDB::makeDirectory(cachefilepath); } std::ofstream fout; std::string tempname = fullcachefilename + ".zip"; fout.open(tempname.c_str(), std::ios::out | std::ios::binary); if ( !fout ) { OE_WARN << LC << "Could not write zip file to " << tempname << std::endl; _options.elevationCachePath().unset(); return NULL; } input_stream.seekg (0, std::ios::end); int length = input_stream.tellg(); input_stream.seekg (0, std::ios::beg); char *buffer = new char[length]; input_stream.read(buffer, length); fout.write(buffer, length); delete[] buffer; fout.close(); //Unzip the file int err; //Open the zip file struct zip* pZip = zip_open(tempname.c_str(), ZIP_CHECKCONS, &err); if (pZip) { //List the files int numFiles = zip_get_num_files(pZip); //OE_DEBUG << tempname << " has " << numFiles << " files " << std::endl; /*for (int i = 0; i < numFiles; ++i) { OE_NOTICE << i << ": " << zip_get_name(pZip, i, 0) << std::endl; }*/ //Find the index within the zip file for the given zip entry int zipIndex = 0; //Open the first file for reading zip_file* pZipFile = zip_fopen_index(pZip, 0, 0); if (pZipFile) { //Read the data from the entry into a std::string int dataSize = 0; std::string data; do{ char* buf = new char[1024]; dataSize = zip_fread(pZipFile, buf, 1024); if (dataSize == 0) { delete [](buf); buf = NULL; } if (buf) { data.append((char*)buf, dataSize); } }while (dataSize > 0); //Close the zip entry and the actual zip file itself zip_fclose(pZipFile); zip_close(pZip); //Write the BIL file to the cache fout.open(fullcachefilename.c_str(), std::ios::out | std::ios::binary); if ( !fout ) { std::cout << "Cannot write bil file"<< std::endl; return NULL; } fout.write((char*)data.c_str(), data.size()); fout.close(); hf = createHeightFieldFromBil((char*)data.c_str(),data.size()); // delete zip file as it has now been processed remove(tempname.c_str()); } } } return hf; }
osg::HeightField* WorldWindSource::createHeightFieldFromBil | ( | char * | buf, |
int | buflength | ||
) | [inline] |
Definition at line 77 of file ReaderWriterWorldWind.cpp.
{ osg::HeightField* hf = new osg::HeightField; //osg::notify(osg::NOTICE) << "Read heightfield image" << std::endl; hf->allocate(150, 150); for( unsigned int row=0; row < 150; row++ ) { for( unsigned int col=0; col < 150; col++ ) { short* ptr = (short*)buf; short val = ptr[col + ((150-row -1)*150)]; hf->setHeight( col, row, (float)val * 0.3048 ); } } return hf; }
osg::Image* WorldWindSource::createImage | ( | const TileKey & | key, |
ProgressCallback * | progress | ||
) | [inline, virtual] |
Creates an image for the given TileKey. The returned object is new and is the responsibility of the caller.
Implements osgEarth::TileSource.
Definition at line 97 of file ReaderWriterWorldWind.cpp.
{ // NYI - eventually, consolidate the "tileservice" plugin into this one //GW return NULL; }
std::string WorldWindSource::createURI | ( | const TileKey & | key | ) | const [inline] |
Definition at line 285 of file ReaderWriterWorldWind.cpp.
{ unsigned int x, y; key.getTileXY(x, y); unsigned int lod = key.getLevelOfDetail(); // flip the y based on level int flippedy = ((9 * powf((int)2,(int)lod)) - 1) - y; std::stringstream buf; buf << *_options.elevationURL() // "http://worldwind25.arc.nasa.gov/wwelevation/wwelevation.aspx?T=srtm30pluszip" << "&L=" << lod << "&X=" << x << "&Y=" << flippedy; std::string bufStr; bufStr = buf.str(); return bufStr; }
virtual std::string WorldWindSource::getExtension | ( | ) | const [inline, virtual] |
Gets the preferred extension for this TileSource
Reimplemented from osgEarth::TileSource.
Definition at line 310 of file ReaderWriterWorldWind.cpp.
{ return "bil"; }
virtual int WorldWindSource::getPixelsPerTile | ( | ) | const [inline, virtual] |
Gets the number of pixels per tile for this TileSource.
Reimplemented from osgEarth::TileSource.
Definition at line 305 of file ReaderWriterWorldWind.cpp.
{
return 150;
}
void WorldWindSource::initialize | ( | const std::string & | referenceURI, |
const Profile * | overrideProfile | ||
) | [inline, virtual] |
Initialize the TileSource. The profile should be computed and set here using setProfile()
Implements osgEarth::TileSource.
Definition at line 63 of file ReaderWriterWorldWind.cpp.
{ setProfile( Profile::create( "epsg:4326", -180.0, -90.0, 180.0, 90.0, "", 18, 9 ) ); if ( !_options.elevationCachePath().isSet() ) { OE_WARN << LC << "Elevation cache path is not set, but is required. No data will be available" << std::endl; } }
WorldWindOptions WorldWindSource::_options [private] |
Reimplemented from osgEarth::TileSource.
Definition at line 316 of file ReaderWriterWorldWind.cpp.