|
osgEarth 2.1.1
|
Inheritance diagram for WorldWindSource:
Collaboration diagram for WorldWindSource: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;
}
Here is the call graph for this function:| 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;
}
Here is the call graph for this function:| 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;
}
Here is the call graph for this function:| 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;
}
Here is the call graph for this function:| 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;
}
}
Here is the call graph for this function:WorldWindOptions WorldWindSource::_options [private] |
Reimplemented from osgEarth::TileSource.
Definition at line 316 of file ReaderWriterWorldWind.cpp.
1.7.3