本文整理汇总了C++中GeoExtent::xMax方法的典型用法代码示例。如果您正苦于以下问题:C++ GeoExtent::xMax方法的具体用法?C++ GeoExtent::xMax怎么用?C++ GeoExtent::xMax使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GeoExtent
的用法示例。
在下文中一共展示了GeoExtent::xMax方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: reproject
GeoImage
GeoImage::crop( const GeoExtent& extent, bool exact, unsigned int width, unsigned int height ) const
{
//Check for equivalence
if ( extent.getSRS()->isEquivalentTo( getSRS() ) )
{
//If we want an exact crop or they want to specify the output size of the image, use GDAL
if (exact || width != 0 || height != 0 )
{
OE_DEBUG << "[osgEarth::GeoImage::crop] Performing exact crop" << std::endl;
//Suggest an output image size
if (width == 0 || height == 0)
{
double xRes = (getExtent().xMax() - getExtent().xMin()) / (double)_image->s();
double yRes = (getExtent().yMax() - getExtent().yMin()) / (double)_image->t();
width = osg::maximum(1u, (unsigned int)((extent.xMax() - extent.xMin()) / xRes));
height = osg::maximum(1u, (unsigned int)((extent.yMax() - extent.yMin()) / yRes));
OE_DEBUG << "[osgEarth::GeoImage::crop] Computed output image size " << width << "x" << height << std::endl;
}
//Note: Passing in the current SRS simply forces GDAL to not do any warping
return reproject( getSRS(), &extent, width, height);
}
else
{
OE_DEBUG << "[osgEarth::GeoImage::crop] Performing non-exact crop " << std::endl;
//If an exact crop is not desired, we can use the faster image cropping code that does no resampling.
double destXMin = extent.xMin();
double destYMin = extent.yMin();
double destXMax = extent.xMax();
double destYMax = extent.yMax();
osg::Image* new_image = ImageUtils::cropImage(
_image.get(),
_extent.xMin(), _extent.yMin(), _extent.xMax(), _extent.yMax(),
destXMin, destYMin, destXMax, destYMax );
//The destination extents may be different than the input extents due to not being able to crop along pixel boundaries.
return new_image?
GeoImage( new_image, GeoExtent( getSRS(), destXMin, destYMin, destXMax, destYMax ) ) :
GeoImage::INVALID;
}
}
else
{
//TODO: just reproject the image before cropping
OE_NOTICE << "[osgEarth::GeoImage::crop] Cropping extent does not have equivalent SpatialReference" << std::endl;
return GeoImage::INVALID;
}
}
示例2: lowerLeft
osg::Node*
SingleKeyNodeFactory::createTile(TileModel* model, bool setupChildrenIfNecessary)
{
// compile the model into a node:
TileNode* tileNode = _modelCompiler->compile( model, _frame );
// see if this tile might have children.
bool prepareForChildren =
setupChildrenIfNecessary &&
model->_tileKey.getLOD() < *_options.maxLOD();
osg::Node* result = 0L;
if ( prepareForChildren )
{
//Compute the min range based on the 2D size of the tile
osg::BoundingSphere bs = tileNode->getBound();
GeoExtent extent = model->_tileKey.getExtent();
GeoPoint lowerLeft(extent.getSRS(), extent.xMin(), extent.yMin(), 0.0, ALTMODE_ABSOLUTE);
GeoPoint upperRight(extent.getSRS(), extent.xMax(), extent.yMax(), 0.0, ALTMODE_ABSOLUTE);
osg::Vec3d ll, ur;
lowerLeft.toWorld( ll );
upperRight.toWorld( ur );
double radius = (ur - ll).length() / 2.0;
float minRange = (float)(radius * _options.minTileRangeFactor().value());
TilePagedLOD* plod = new TilePagedLOD( _engineUID, _liveTiles, _deadTiles );
plod->setCenter ( bs.center() );
plod->addChild ( tileNode );
plod->setRange ( 0, minRange, FLT_MAX );
plod->setFileName( 1, Stringify() << tileNode->getKey().str() << "." << _engineUID << ".osgearth_engine_mp_tile" );
plod->setRange ( 1, 0, minRange );
#if USE_FILELOCATIONCALLBACK
osgDB::Options* options = Registry::instance()->cloneOrCreateOptions();
options->setFileLocationCallback( new FileLocationCallback() );
plod->setDatabaseOptions( options );
#endif
result = plod;
// this one rejects back-facing tiles:
if ( _frame.getMapInfo().isGeocentric() && _options.clusterCulling() == true )
{
osg::HeightField* hf =
model->_elevationData.getHeightField();
result->addCullCallback( HeightFieldUtils::createClusterCullingCallback(
hf,
tileNode->getKey().getProfile()->getSRS()->getEllipsoid(),
*_options.verticalScale() ) );
}
}
else
{
result = tileNode;
}
return result;
}
示例3: lowerLeft
osg::Node*
SerialKeyNodeFactory::createTile(TileModel* model,
bool tileHasRealData)
{
// compile the model into a node:
TileNode* tileNode = _modelCompiler->compile( model );
// see if this tile might have children.
bool prepareForChildren =
(tileHasRealData || (_options.minLOD().isSet() && model->_tileKey.getLOD() < *_options.minLOD())) &&
model->_tileKey.getLOD() < *_options.maxLOD();
osg::Node* result = 0L;
if ( prepareForChildren )
{
//Compute the min range based on the 2D size of the tile
osg::BoundingSphere bs = tileNode->getBound();
GeoExtent extent = model->_tileKey.getExtent();
GeoPoint lowerLeft(extent.getSRS(), extent.xMin(), extent.yMin(), 0.0, ALTMODE_ABSOLUTE);
GeoPoint upperRight(extent.getSRS(), extent.xMax(), extent.yMax(), 0.0, ALTMODE_ABSOLUTE);
osg::Vec3d ll, ur;
lowerLeft.toWorld( ll );
upperRight.toWorld( ur );
double radius = (ur - ll).length() / 2.0;
float minRange = (float)(radius * _options.minTileRangeFactor().value());
osgDB::Options* dbOptions = Registry::instance()->cloneOrCreateOptions();
TileGroup* plod = new TileGroup(tileNode, _engineUID, _liveTiles.get(), _deadTiles.get(), dbOptions);
plod->setSubtileRange( minRange );
#if USE_FILELOCATIONCALLBACK
dbOptions->setFileLocationCallback( new FileLocationCallback() );
#endif
result = plod;
}
else
{
result = tileNode;
}
// this one rejects back-facing tiles:
if ( _mapInfo.isGeocentric() && _options.clusterCulling() == true )
{
osg::HeightField* hf =
model->_elevationData.getHeightField();
result->addCullCallback( HeightFieldUtils::createClusterCullingCallback(
hf,
tileNode->getKey().getProfile()->getSRS()->getEllipsoid(),
*_options.verticalScale() ) );
}
return result;
}
示例4: e
TileMap*
TileMap::create(const std::string& url,
const Profile* profile,
const DataExtentList& dataExtents,
const std::string& format,
int tile_width,
int tile_height)
{
const GeoExtent& ex = profile->getExtent();
TileMap* tileMap = new TileMap();
tileMap->setProfileType(profile->getProfileType());
tileMap->setExtents(ex.xMin(), ex.yMin(), ex.xMax(), ex.yMax());
tileMap->setOrigin(ex.xMin(), ex.yMin());
tileMap->_filename = url;
tileMap->_srs = getHorizSRSString(profile->getSRS());
tileMap->_vsrs = profile->getSRS()->getVertInitString();
tileMap->_format.setWidth( tile_width );
tileMap->_format.setHeight( tile_height );
profile->getNumTiles( 0, tileMap->_numTilesWide, tileMap->_numTilesHigh );
// format can be a mime-type or an extension:
std::string::size_type p = format.find('/');
if ( p == std::string::npos )
{
tileMap->_format.setExtension(format);
tileMap->_format.setMimeType( Registry::instance()->getMimeTypeForExtension(format) );
}
else
{
tileMap->_format.setMimeType(format);
tileMap->_format.setExtension( Registry::instance()->getExtensionForMimeType(format) );
}
//Add the data extents
tileMap->getDataExtents().insert(tileMap->getDataExtents().end(), dataExtents.begin(), dataExtents.end());
// If we have some data extents specified then make a nicer bounds than the
if (!tileMap->getDataExtents().empty())
{
// Get the union of all the extents
GeoExtent e(tileMap->getDataExtents()[0]);
for (unsigned int i = 1; i < tileMap->getDataExtents().size(); i++)
{
e.expandToInclude(tileMap->getDataExtents()[i]);
}
// Convert the bounds to the output profile
GeoExtent bounds = e.transform(profile->getSRS());
tileMap->setExtents(bounds.xMin(), bounds.yMin(), bounds.xMax(), bounds.yMax());
}
tileMap->generateTileSets();
tileMap->computeMinMaxLevel();
return tileMap;
}
示例5: getTileDimensions
void
Profile::addIntersectingTiles(const GeoExtent& key_ext, unsigned localLOD, std::vector<TileKey>& out_intersectingKeys) const
{
// assume a non-crossing extent here.
if ( key_ext.crossesAntimeridian() )
{
OE_WARN << "Profile::addIntersectingTiles cannot process date-line cross" << std::endl;
return;
}
int tileMinX, tileMaxX;
int tileMinY, tileMaxY;
double destTileWidth, destTileHeight;
getTileDimensions(localLOD, destTileWidth, destTileHeight);
//OE_DEBUG << std::fixed << " Source Tile: " << key.getLevelOfDetail() << " (" << keyWidth << ", " << keyHeight << ")" << std::endl;
//OE_DEBUG << std::fixed << " Dest Size: " << destLOD << " (" << destTileWidth << ", " << destTileHeight << ")" << std::endl;
double east = key_ext.xMax() - _extent.xMin();
bool xMaxOnTileBoundary = fmod(east, destTileWidth) == 0.0;
double south = _extent.yMax() - key_ext.yMin();
bool yMaxOnTileBoundary = fmod(south, destTileHeight) == 0.0;
tileMinX = (int)((key_ext.xMin() - _extent.xMin()) / destTileWidth);
tileMaxX = (int)(east / destTileWidth) - (xMaxOnTileBoundary ? 1 : 0);
tileMinY = (int)((_extent.yMax() - key_ext.yMax()) / destTileHeight);
tileMaxY = (int)(south / destTileHeight) - (yMaxOnTileBoundary ? 1 : 0);
unsigned int numWide, numHigh;
getNumTiles(localLOD, numWide, numHigh);
// bail out if the tiles are out of bounds.
if ( tileMinX >= (int)numWide || tileMinY >= (int)numHigh ||
tileMaxX < 0 || tileMaxY < 0 )
{
return;
}
tileMinX = osg::clampBetween(tileMinX, 0, (int)numWide-1);
tileMaxX = osg::clampBetween(tileMaxX, 0, (int)numWide-1);
tileMinY = osg::clampBetween(tileMinY, 0, (int)numHigh-1);
tileMaxY = osg::clampBetween(tileMaxY, 0, (int)numHigh-1);
OE_DEBUG << std::fixed << " Dest Tiles: " << tileMinX << "," << tileMinY << " => " << tileMaxX << "," << tileMaxY << std::endl;
for (int i = tileMinX; i <= tileMaxX; ++i)
{
for (int j = tileMinY; j <= tileMaxY; ++j)
{
//TODO: does not support multi-face destination keys.
out_intersectingKeys.push_back( TileKey(localLOD, i, j, this) );
}
}
}
示例6:
GeoLocator::GeoLocator( const osgTerrain::Locator& prototype, const GeoExtent& dataExtent, const GeoExtent& displayExtent ) :
osgTerrain::Locator( prototype ),
_dataExtent( dataExtent ),
_inverseCalculated(false)
{
// assume they are the same SRS
_x0 = osg::clampBetween( (displayExtent.xMin()-dataExtent.xMin())/dataExtent.width(), 0.0, 1.0 );
_x1 = osg::clampBetween( (displayExtent.xMax()-dataExtent.xMin())/dataExtent.width(), 0.0, 1.0 );
_y0 = osg::clampBetween( (displayExtent.yMin()-dataExtent.yMin())/dataExtent.height(), 0.0, 1.0 );
_y1 = osg::clampBetween( (displayExtent.yMax()-dataExtent.yMin())/dataExtent.height(), 0.0, 1.0 );
}
示例7: GeoExtent
GeoExtent
UnifiedCubeProfile::transformGcsExtentOnFace( const GeoExtent& gcsExtent, int face ) const
{
if ( face < 4 )
{
const GeoExtent& fex = _faceExtent_gcs[face];
return GeoExtent(
getSRS(),
(double)face + (gcsExtent.xMin()-fex.xMin()) / fex.width(),
(gcsExtent.yMin()-fex.yMin()) / fex.height(),
(double)face + (gcsExtent.xMax()-fex.xMin()) / fex.width(),
(gcsExtent.yMax()-fex.yMin()) / fex.height() );
}
else
{
// transform all 4 corners; then do the min/max for x/y.
double lon[4] = { gcsExtent.xMin(), gcsExtent.xMax(), gcsExtent.xMax(), gcsExtent.xMin() };
double lat[4] = { gcsExtent.yMin(), gcsExtent.yMin(), gcsExtent.yMax(), gcsExtent.yMax() };
double x[4], y[4];
for( int i=0; i<4; ++i )
{
int dummy;
if ( ! CubeUtils::latLonToFaceCoords( lat[i], lon[i], x[i], y[i], dummy, face ) )
{
OE_WARN << LC << "transformGcsExtentOnFace, ll2fc failed" << std::endl;
}
}
double xmin = SMALLEST( x[0], x[1], x[2], x[3] );
double xmax = LARGEST( x[0], x[1], x[2], x[3] );
double ymin = SMALLEST( y[0], y[1], y[2], y[3] );
double ymax = LARGEST( y[0], y[1], y[2], y[3] );
CubeUtils::faceToCube( xmin, ymin, face );
CubeUtils::faceToCube( xmax, ymax, face );
return GeoExtent( getSRS(), xmin, ymin, xmax, ymax );
}
}
示例8: round
void
Profile::addIntersectingTiles(const GeoExtent& key_ext, unsigned localLOD, std::vector<TileKey>& out_intersectingKeys) const
{
// assume a non-crossing extent here.
if ( key_ext.crossesAntimeridian() )
{
OE_WARN << "Profile::addIntersectingTiles cannot process date-line cross" << std::endl;
return;
}
int tileMinX, tileMaxX;
int tileMinY, tileMaxY;
// Special path for mercator (does NOT work for cube, e.g.)
if ( key_ext.getSRS()->isMercator() )
{
int precision = 5;
double eps = 0.001;
double keyWidth = round(key_ext.width(), precision);
int destLOD = 0;
double w, h;
getTileDimensions(0, w, h);
for(; (round(w,precision) - keyWidth) > eps; w*=0.5, h*=0.5, destLOD++ );
double destTileWidth, destTileHeight;
getTileDimensions( destLOD, destTileWidth, destTileHeight );
destTileWidth = round(destTileWidth, precision);
destTileHeight = round(destTileHeight, precision);
tileMinX = quantize( ((key_ext.xMin() - _extent.xMin()) / destTileWidth), eps );
tileMaxX = (int)((key_ext.xMax() - _extent.xMin()) / destTileWidth);
tileMinY = quantize( ((_extent.yMax() - key_ext.yMax()) / destTileHeight), eps );
tileMaxY = (int) ((_extent.yMax() - key_ext.yMin()) / destTileHeight);
}
else
{
double destTileWidth, destTileHeight;
getTileDimensions(localLOD, destTileWidth, destTileHeight);
//OE_DEBUG << std::fixed << " Source Tile: " << key.getLevelOfDetail() << " (" << keyWidth << ", " << keyHeight << ")" << std::endl;
//OE_DEBUG << std::fixed << " Dest Size: " << destLOD << " (" << destTileWidth << ", " << destTileHeight << ")" << std::endl;
tileMinX = (int)((key_ext.xMin() - _extent.xMin()) / destTileWidth);
tileMaxX = (int)((key_ext.xMax() - _extent.xMin()) / destTileWidth);
tileMinY = (int)((_extent.yMax() - key_ext.yMax()) / destTileHeight);
tileMaxY = (int)((_extent.yMax() - key_ext.yMin()) / destTileHeight);
}
unsigned int numWide, numHigh;
getNumTiles(localLOD, numWide, numHigh);
// bail out if the tiles are out of bounds.
if ( tileMinX >= (int)numWide || tileMinY >= (int)numHigh ||
tileMaxX < 0 || tileMaxY < 0 )
{
return;
}
tileMinX = osg::clampBetween(tileMinX, 0, (int)numWide-1);
tileMaxX = osg::clampBetween(tileMaxX, 0, (int)numWide-1);
tileMinY = osg::clampBetween(tileMinY, 0, (int)numHigh-1);
tileMaxY = osg::clampBetween(tileMaxY, 0, (int)numHigh-1);
OE_DEBUG << std::fixed << " Dest Tiles: " << tileMinX << "," << tileMinY << " => " << tileMaxX << "," << tileMaxY << std::endl;
for (int i = tileMinX; i <= tileMaxX; ++i)
{
for (int j = tileMinY; j <= tileMaxY; ++j)
{
//TODO: does not support multi-face destination keys.
out_intersectingKeys.push_back( TileKey(localLOD, i, j, this) );
}
}
}
示例9: v
void
TFSPackager::package( FeatureSource* features, const std::string& destination, const std::string& layername, const std::string& description )
{
if (!_destSRSString.empty())
{
_srs = SpatialReference::create( _destSRSString );
}
//Get the destination SRS from the feature source if it's not already set
if (!_srs.valid())
{
_srs = features->getFeatureProfile()->getSRS();
}
//Get the extent of the dataset, or use the custom extent value
GeoExtent srsExtent = _customExtent;
if (!srsExtent.isValid())
srsExtent = features->getFeatureProfile()->getExtent();
//Transform to lat/lon extents
GeoExtent extent = srsExtent.transform( _srs.get() );
osg::ref_ptr< const osgEarth::Profile > profile = osgEarth::Profile::create(extent.getSRS(), extent.xMin(), extent.yMin(), extent.xMax(), extent.yMax(), 1, 1);
TileKey rootKey = TileKey(0, 0, 0, profile );
osg::ref_ptr< FeatureTile > root = new FeatureTile( rootKey );
//Loop through all the features and try to insert them into the quadtree
osg::ref_ptr< FeatureCursor > cursor = features->createFeatureCursor( _query );
int added = 0;
int failed = 0;
int skipped = 0;
int highestLevel = 0;
while (cursor.valid() && cursor->hasMore())
{
osg::ref_ptr< Feature > feature = cursor->nextFeature();
//Reproject the feature to the dest SRS if it's not already
if (!feature->getSRS()->isEquivalentTo( _srs ) )
{
feature->transform( _srs );
}
if (feature->getGeometry() && feature->getGeometry()->getBounds().valid() && feature->getGeometry()->isValid())
{
AddFeatureVisitor v(feature.get(), _maxFeatures, _firstLevel, _maxLevel, _method);
root->accept( &v );
if (!v._added)
{
OE_NOTICE << "Failed to add feature " << feature->getFID() << std::endl;
failed++;
}
else
{
if (highestLevel < v._levelAdded)
{
highestLevel = v._levelAdded;
}
added++;
OE_DEBUG << "Added " << added << std::endl;
}
}
else
{
OE_NOTICE << "Skipping feature " << feature->getFID() << " with null or invalid geometry" << std::endl;
skipped++;
}
}
OE_NOTICE << "Added=" << added << " Skipped=" << skipped << " Failed=" << failed << std::endl;
#if 1
// Print the width of tiles at each level
for (int i = 0; i <= highestLevel; ++i)
{
TileKey tileKey(i, 0, 0, profile);
GeoExtent tileExtent = tileKey.getExtent();
OE_NOTICE << "Level " << i << " tile size: " << tileExtent.width() << std::endl;
}
#endif
WriteFeaturesVisitor write(features, destination, _method, _srs);
root->accept( &write );
//Write out the meta doc
TFSLayer layer;
layer.setTitle( layername );
layer.setAbstract( description );
layer.setFirstLevel( _firstLevel );
layer.setMaxLevel( highestLevel );
layer.setExtent( profile->getExtent() );
layer.setSRS( _srs.get() );
TFSReaderWriter::write( layer, osgDB::concatPaths( destination, "tfs.xml"));
}
示例10: lowerLeft
void
SerialKeyNodeFactory::addTile(Tile* tile, bool tileHasRealData, bool tileHasLodBlending, osg::Group* parent )
{
// associate this tile with the terrain:
tile->setTerrainTechnique( _terrain->cloneTechnique() );
tile->attachToTerrain( _terrain );
// assemble a URI for this tile's child group:
std::stringstream buf;
buf << tile->getKey().str() << "." << _engineUID << ".osgearth_osgterrain_tile";
std::string uri; uri = buf.str();
osg::Node* result = 0L;
// Only add the next tile if all the following are true:
// 1. Either there's real tile data, or a maxLOD is explicity set in the options;
// 2. The tile isn't blacklisted; and
// 3. We are still below the max LOD.
bool wrapInPagedLOD =
(tileHasRealData || _options.maxLOD().isSet()) &&
!osgEarth::Registry::instance()->isBlacklisted( uri ) &&
tile->getKey().getLevelOfDetail() < (unsigned)*_options.maxLOD();
if ( wrapInPagedLOD )
{
osg::BoundingSphere bs = tile->getBound();
double maxRange = 1e10;
#if 0
//Compute the min range based on the actual bounds of the tile. This can break down if you have very high resolution
//data with elevation variations and you can run out of memory b/c the elevation change is greater than the actual size of the tile so you end up
//inifinitely subdividing (or at least until you run out of data or memory)
double minRange = bs.radius() * _options.minTileRangeFactor().value();
#else
//double origMinRange = bs.radius() * _options.minTileRangeFactor().value();
//Compute the min range based on the 2D size of the tile
GeoExtent extent = tile->getKey().getExtent();
GeoPoint lowerLeft(extent.getSRS(), extent.xMin(), extent.yMin());
GeoPoint upperRight(extent.getSRS(), extent.xMax(), extent.yMax());
osg::Vec3d ll, ur;
lowerLeft.toWorld( ll );
upperRight.toWorld( ur );
double radius = (ur - ll).length() / 2.0;
double minRange = radius * _options.minTileRangeFactor().value();
#endif
// create a PLOD so we can keep subdividing:
osg::PagedLOD* plod = new osg::PagedLOD();
plod->setCenter( bs.center() );
plod->addChild( tile, minRange, maxRange );
plod->setFileName( 1, uri );
plod->setRange ( 1, 0, minRange );
plod->setUserData( new MapNode::TileRangeData(minRange, maxRange) );
#if USE_FILELOCATIONCALLBACK
osgDB::Options* options = Registry::instance()->cloneOrCreateOptions();
options->setFileLocationCallback( new FileLocationCallback() );
plod->setDatabaseOptions( options );
#endif
result = plod;
if ( tileHasLodBlending )
{
// Make the LOD transition distance, and a measure of how
// close the tile is to an LOD change, to shaders.
result->addCullCallback(new Drivers::LODFactorCallback);
}
}
else
{
result = tile;
}
// this cull callback dynamically adjusts the LOD scale based on distance-to-camera:
if ( _options.lodFallOff().isSet() && *_options.lodFallOff() > 0.0 )
{
result->addCullCallback( new DynamicLODScaleCallback(*_options.lodFallOff()) );
}
// this one rejects back-facing tiles:
if ( _mapInfo.isGeocentric() && _options.clusterCulling() == true )
{
result->addCullCallback( HeightFieldUtils::createClusterCullingCallback(
static_cast<osgTerrain::HeightFieldLayer*>(tile->getElevationLayer())->getHeightField(),
tile->getLocator()->getEllipsoidModel(),
tile->getVerticalScale() ) );
}
parent->addChild( result );
}
示例11: lowerLeft
void
SerialKeyNodeFactory::addTile(TileModel* model, bool tileHasRealData, bool tileHasLodBlending, osg::Group* parent )
{
// create a node:
TileNode* tileNode = new TileNode( model->_tileKey, model->_tileLocator );
// install the tile model and compile it:
tileNode->setTileModel( model );
tileNode->compile( _modelCompiler.get() );
// assemble a URI for this tile's child group:
std::string uri = Stringify() << model->_tileKey.str() << "." << _engineUID << ".osgearth_engine_mp_tile";
osg::Node* result = 0L;
// Only add the next tile if all the following are true:
// 1. Either there's real tile data, or a minLOD is explicity set in the options;
// 2. The tile isn't blacklisted; and
// 3. We are still below the maximim LOD.
bool wrapInPagedLOD =
(tileHasRealData || (_options.minLOD().isSet() && model->_tileKey.getLOD() < *_options.minLOD())) &&
!osgEarth::Registry::instance()->isBlacklisted( uri ) &&
model->_tileKey.getLOD() < *_options.maxLOD();
if ( wrapInPagedLOD )
{
osg::BoundingSphere bs = tileNode->getBound();
float maxRange = FLT_MAX;
//Compute the min range based on the 2D size of the tile
GeoExtent extent = model->_tileKey.getExtent();
GeoPoint lowerLeft(extent.getSRS(), extent.xMin(), extent.yMin(), 0.0, ALTMODE_ABSOLUTE);
GeoPoint upperRight(extent.getSRS(), extent.xMax(), extent.yMax(), 0.0, ALTMODE_ABSOLUTE);
osg::Vec3d ll, ur;
lowerLeft.toWorld( ll );
upperRight.toWorld( ur );
double radius = (ur - ll).length() / 2.0;
float minRange = (float)(radius * _options.minTileRangeFactor().value());
// create a PLOD so we can keep subdividing:
osg::PagedLOD* plod = new CustomPagedLOD( _liveTiles.get(), _deadTiles.get() );
plod->setCenter( bs.center() );
plod->addChild( tileNode );
plod->setRangeMode( *_options.rangeMode() );
plod->setFileName( 1, uri );
if (plod->getRangeMode() == osg::LOD::PIXEL_SIZE_ON_SCREEN)
{
static const float sqrt2 = sqrt(2.0f);
minRange = 0;
maxRange = (*_options.tilePixelSize()) * sqrt2;
plod->setRange( 0, minRange, maxRange );
plod->setRange( 1, maxRange, FLT_MAX );
}
else
{
plod->setRange( 0, minRange, maxRange );
plod->setRange( 1, 0, minRange );
}
plod->setUserData( new MapNode::TileRangeData(minRange, maxRange) );
#if USE_FILELOCATIONCALLBACK
osgDB::Options* options = Registry::instance()->cloneOrCreateOptions();
options->setFileLocationCallback( new FileLocationCallback() );
plod->setDatabaseOptions( options );
#endif
result = plod;
if ( tileHasLodBlending )
{
// Make the LOD transition distance, and a measure of how
// close the tile is to an LOD change, to shaders.
result->addCullCallback(new LODFactorCallback);
}
}
else
{
result = tileNode;
}
// this cull callback dynamically adjusts the LOD scale based on distance-to-camera:
if ( _options.lodFallOff().isSet() && *_options.lodFallOff() > 0.0 )
{
result->addCullCallback( new DynamicLODScaleCallback(*_options.lodFallOff()) );
}
// this one rejects back-facing tiles:
if ( _mapInfo.isGeocentric() && _options.clusterCulling() == true )
{
osg::HeightField* hf =
model->_elevationData.getHFLayer()->getHeightField();
result->addCullCallback( HeightFieldUtils::createClusterCullingCallback(
//.........这里部分代码省略.........
示例12: renderFeaturesForStyle
//.........这里部分代码省略.........
}
// "relative line size" means that the line width is expressed in (approx) pixels
// rather than in map units
if ( _options.relativeLineSize() == true )
buffer.distance() = xres * lineWidth;
else
buffer.distance() = lineWidth;
buffer.push( linesToBuffer, context );
}
// First, transform the features into the map's SRS:
TransformFilter xform( imageExtent.getSRS() );
xform.setLocalizeCoordinates( false );
context = xform.push( features, context );
// set up the AGG renderer:
agg::rendering_buffer rbuf( image->data(), image->s(), image->t(), image->s()*4 );
// Create the renderer and the rasterizer
agg::renderer<agg::span_abgr32> ren(rbuf);
agg::rasterizer ras;
// Setup the rasterizer
ras.gamma(1.3);
ras.filling_rule(agg::fill_even_odd);
GeoExtent cropExtent = GeoExtent(imageExtent);
cropExtent.scale(1.1, 1.1);
osg::ref_ptr<Symbology::Polygon> cropPoly = new Symbology::Polygon( 4 );
cropPoly->push_back( osg::Vec3d( cropExtent.xMin(), cropExtent.yMin(), 0 ));
cropPoly->push_back( osg::Vec3d( cropExtent.xMax(), cropExtent.yMin(), 0 ));
cropPoly->push_back( osg::Vec3d( cropExtent.xMax(), cropExtent.yMax(), 0 ));
cropPoly->push_back( osg::Vec3d( cropExtent.xMin(), cropExtent.yMax(), 0 ));
double lineWidth = 1.0;
if ( masterLine )
lineWidth = (double)masterLine->stroke()->width().value();
osg::Vec4 color = osg::Vec4(1, 1, 1, 1);
if ( masterLine )
color = masterLine->stroke()->color();
// render the features
for(FeatureList::iterator i = features.begin(); i != features.end(); i++)
{
Feature* feature = i->get();
//bool first = bd->_pass == 0 && i == features.begin();
Geometry* geometry = feature->getGeometry();
osg::ref_ptr< Geometry > croppedGeometry;
if ( ! geometry->crop( cropPoly.get(), croppedGeometry ) )
continue;
// set up a default color:
osg::Vec4 c = color;
unsigned int a = (unsigned int)(127+(c.a()*255)/2); // scale alpha up
agg::rgba8 fgColor( (unsigned int)(c.r()*255), (unsigned int)(c.g()*255), (unsigned int)(c.b()*255), a );
GeometryIterator gi( croppedGeometry.get() );
while( gi.hasMore() )
{
c = color;
示例13: round
void
Profile::addIntersectingTiles(const GeoExtent& key_ext, std::vector<TileKey>& out_intersectingKeys) const
{
// assume a non-crossing extent here.
if ( key_ext.crossesAntimeridian() )
{
OE_WARN << "Profile::addIntersectingTiles cannot process date-line cross" << std::endl;
return;
}
#if 0 // works for meracator; does NOT work for cube
int precision = 5;
double eps = 0.001;
double keyWidth = round(key_ext.width(), precision);
int destLOD = 0;
double w, h;
getTileDimensions(0, w, h);
for(; (round(w,precision) - keyWidth) > eps; w*=0.5, h*=0.5, destLOD++ );
double destTileWidth, destTileHeight;
getTileDimensions( destLOD, destTileWidth, destTileHeight );
destTileWidth = round(destTileWidth, precision);
destTileHeight = round(destTileHeight, precision);
int tileMinX = quantize( ((key_ext.xMin() - _extent.xMin()) / destTileWidth), eps );
int tileMaxX = (int)((key_ext.xMax() - _extent.xMin()) / destTileWidth);
int tileMinY = quantize( ((_extent.yMax() - key_ext.yMax()) / destTileHeight), eps );
int tileMaxY = (int) ((_extent.yMax() - key_ext.yMin()) / destTileHeight);
#else
double keyWidth = key_ext.width();
double keyHeight = key_ext.height();
// bail out if the key has a null extent. This might happen is the original key represents an
// area in one profile that is out of bounds in this profile.
if ( keyWidth <= 0.0 && keyHeight <= 0.0 )
return;
double keySpan = std::min( keyWidth, keyHeight );
double keyArea = keyWidth * keyHeight;
double keyAvg = 0.5*(keyWidth+keyHeight);
int destLOD = 1;
double destTileWidth, destTileHeight;
int currLOD = 0;
destLOD = currLOD;
getTileDimensions(destLOD, destTileWidth, destTileHeight);
while( true )
{
currLOD++;
double w, h;
getTileDimensions(currLOD, w, h);
if ( w < keyAvg || h < keyAvg ) break;
destLOD = currLOD;
destTileWidth = w;
destTileHeight = h;
}
//OE_DEBUG << std::fixed << " Source Tile: " << key.getLevelOfDetail() << " (" << keyWidth << ", " << keyHeight << ")" << std::endl;
//OE_DEBUG << std::fixed << " Dest Size: " << destLOD << " (" << destTileWidth << ", " << destTileHeight << ")" << std::endl;
int tileMinX = (int)((key_ext.xMin() - _extent.xMin()) / destTileWidth);
int tileMaxX = (int)((key_ext.xMax() - _extent.xMin()) / destTileWidth);
int tileMinY = (int)((_extent.yMax() - key_ext.yMax()) / destTileHeight);
int tileMaxY = (int)((_extent.yMax() - key_ext.yMin()) / destTileHeight);
#endif
unsigned int numWide, numHigh;
getNumTiles(destLOD, numWide, numHigh);
// bail out if the tiles are out of bounds.
if ( tileMinX >= (int)numWide || tileMinY >= (int)numHigh ||
tileMaxX < 0 || tileMaxY < 0 )
{
return;
}
tileMinX = osg::clampBetween(tileMinX, 0, (int)numWide-1);
tileMaxX = osg::clampBetween(tileMaxX, 0, (int)numWide-1);
tileMinY = osg::clampBetween(tileMinY, 0, (int)numHigh-1);
tileMaxY = osg::clampBetween(tileMaxY, 0, (int)numHigh-1);
OE_DEBUG << std::fixed << " Dest Tiles: " << tileMinX << "," << tileMinY << " => " << tileMaxX << "," << tileMaxY << std::endl;
for (int i = tileMinX; i <= tileMaxX; ++i)
{
for (int j = tileMinY; j <= tileMaxY; ++j)
{
//TODO: does not support multi-face destination keys.
out_intersectingKeys.push_back( TileKey(destLOD, i, j, this) );
}
//.........这里部分代码省略.........
示例14: lowerLeft
osg::Node*
SingleKeyNodeFactory::createTile(TileModel* model,
bool setupChildrenIfNecessary,
ProgressCallback* progress)
{
#ifdef EXPERIMENTAL_TILE_NODE_CACHE
osg::ref_ptr<TileNode> tileNode;
TileNodeCache::Record rec;
cache.get(model->_tileKey, rec);
if ( rec.valid() )
{
tileNode = rec.value().get();
}
else
{
tileNode = _modelCompiler->compile( model, _frame );
cache.insert(model->_tileKey, tileNode);
}
#else
// compile the model into a node:
TileNode* tileNode = _modelCompiler->compile(model, _frame, progress);
#endif
// see if this tile might have children.
bool prepareForChildren =
setupChildrenIfNecessary &&
model->_tileKey.getLOD() < *_options.maxLOD();
osg::Node* result = 0L;
if ( prepareForChildren )
{
osg::BoundingSphere bs = tileNode->getBound();
TilePagedLOD* plod = new TilePagedLOD( _engineUID, _liveTiles, _deadTiles );
plod->setCenter ( bs.center() );
plod->addChild ( tileNode );
plod->setFileName( 1, Stringify() << tileNode->getKey().str() << "." << _engineUID << ".osgearth_engine_mp_tile" );
if ( _options.rangeMode().value() == osg::LOD::DISTANCE_FROM_EYE_POINT )
{
//Compute the min range based on the 2D size of the tile
GeoExtent extent = model->_tileKey.getExtent();
GeoPoint lowerLeft(extent.getSRS(), extent.xMin(), extent.yMin(), 0.0, ALTMODE_ABSOLUTE);
GeoPoint upperRight(extent.getSRS(), extent.xMax(), extent.yMax(), 0.0, ALTMODE_ABSOLUTE);
osg::Vec3d ll, ur;
lowerLeft.toWorld( ll );
upperRight.toWorld( ur );
double radius = (ur - ll).length() / 2.0;
float minRange = (float)(radius * _options.minTileRangeFactor().value());
plod->setRange( 0, minRange, FLT_MAX );
plod->setRange( 1, 0, minRange );
plod->setRangeMode( osg::LOD::DISTANCE_FROM_EYE_POINT );
}
else
{
plod->setRange( 0, 0.0f, _options.tilePixelSize().value() );
plod->setRange( 1, _options.tilePixelSize().value(), FLT_MAX );
plod->setRangeMode( osg::LOD::PIXEL_SIZE_ON_SCREEN );
}
// DBPager will set a priority based on the ratio range/maxRange.
// This will offset that number with a full LOD #, giving LOD precedence.
// Experimental.
//plod->setPriorityScale( 1, model->_tileKey.getLOD()+1 );
#if USE_FILELOCATIONCALLBACK
osgDB::Options* options = plod->getOrCreateDBOptions();
options->setFileLocationCallback( new FileLocationCallback() );
#endif
result = plod;
// this one rejects back-facing tiles:
if ( _frame.getMapInfo().isGeocentric() && _options.clusterCulling() == true )
{
osg::HeightField* hf =
model->_elevationData.getHeightField();
result->addCullCallback( HeightFieldUtils::createClusterCullingCallback(
hf,
tileNode->getKey().getProfile()->getSRS()->getEllipsoid(),
*_options.verticalScale() ) );
}
}
else
{
result = tileNode;
}
return result;
}
示例15: ts
osg::Node*
MGRSGraticule::buildSQIDTiles( const std::string& gzd )
{
const GeoExtent& extent = _gzd[gzd];
// parse the GZD into its components:
unsigned zone;
char letter;
sscanf( gzd.c_str(), "%u%c", &zone, &letter );
TextSymbol* textSym = _options->secondaryStyle()->get<TextSymbol>();
if ( !textSym )
textSym = _options->primaryStyle()->getOrCreate<TextSymbol>();
AltitudeSymbol* alt = _options->secondaryStyle()->get<AltitudeSymbol>();
double h = 0.0;
TextSymbolizer ts( textSym );
MGRSFormatter mgrs(MGRSFormatter::PRECISION_100000M);
osg::Geode* textGeode = new osg::Geode();
textGeode->getOrCreateStateSet()->setRenderBinDetails( 9999, "DepthSortedBin" );
textGeode->getOrCreateStateSet()->setAttributeAndModes( _depthAttribute, 1 );
const SpatialReference* ecefSRS = extent.getSRS()->getECEF();
osg::Vec3d centerMap, centerECEF;
extent.getCentroid(centerMap.x(), centerMap.y());
extent.getSRS()->transform(centerMap, ecefSRS, centerECEF);
//extent.getSRS()->transformToECEF(centerMap, centerECEF);
osg::Matrix local2world;
ecefSRS->createLocalToWorld( centerECEF, local2world ); //= ECEF::createLocalToWorld(centerECEF);
osg::Matrix world2local;
world2local.invert(local2world);
FeatureList features;
std::vector<GeoExtent> sqidExtents;
// UTM:
if ( letter > 'B' && letter < 'Y' )
{
// grab the SRS for the current UTM zone:
// TODO: AL/AA designation??
const SpatialReference* utm = SpatialReference::create(
Stringify() << "+proj=utm +zone=" << zone << " +north +units=m" );
// transform the four corners of the tile to UTM.
osg::Vec3d gzdUtmSW, gzdUtmSE, gzdUtmNW, gzdUtmNE;
extent.getSRS()->transform( osg::Vec3d(extent.xMin(),extent.yMin(),h), utm, gzdUtmSW );
extent.getSRS()->transform( osg::Vec3d(extent.xMin(),extent.yMax(),h), utm, gzdUtmNW );
extent.getSRS()->transform( osg::Vec3d(extent.xMax(),extent.yMin(),h), utm, gzdUtmSE );
extent.getSRS()->transform( osg::Vec3d(extent.xMax(),extent.yMax(),h), utm, gzdUtmNE );
// find the southern boundary of the first full SQID tile in the GZD tile.
double southSQIDBoundary = gzdUtmSW.y(); //extentUTM.yMin();
double remainder = fmod( southSQIDBoundary, 100000.0 );
if ( remainder > 0.0 )
southSQIDBoundary += (100000.0 - remainder);
// find the min/max X for this cell in UTM:
double xmin = extent.yMin() >= 0.0 ? gzdUtmSW.x() : gzdUtmNW.x();
double xmax = extent.yMin() >= 0.0 ? gzdUtmSE.x() : gzdUtmNE.x();
// Record the UTM extent of each SQID cell in this tile.
// Go from the south boundary northwards:
for( double y = southSQIDBoundary; y < gzdUtmNW.y(); y += 100000.0 )
{
// start at the central meridian (500K) and go west:
for( double x = 500000.0; x > xmin; x -= 100000.0 )
{
sqidExtents.push_back( GeoExtent(utm, x-100000.0, y, x, y+100000.0) );
}
// then start at the central meridian and go east:
for( double x = 500000.0; x < xmax; x += 100000.0 )
{
sqidExtents.push_back( GeoExtent(utm, x, y, x+100000.0, y+100000.0) );
}
}
for( std::vector<GeoExtent>::iterator i = sqidExtents.begin(); i != sqidExtents.end(); ++i )
{
GeoExtent utmEx = *i;
// now, clamp each of the points in the UTM SQID extent to the map-space
// boundaries of the GZD tile. (We only need to clamp in the X dimension,
// Y geometry is allowed to overflow.) Also, skip NE, we don't need it.
double r, xlimit;
osg::Vec3d sw(utmEx.xMin(), utmEx.yMin(), 0);
r = (sw.y()-gzdUtmSW.y())/(gzdUtmNW.y()-gzdUtmSW.y());
xlimit = gzdUtmSW.x() + r * (gzdUtmNW.x() - gzdUtmSW.x());
if ( sw.x() < xlimit ) sw.x() = xlimit;
osg::Vec3d nw(utmEx.xMin(), utmEx.yMax(), 0);
r = (nw.y()-gzdUtmSW.y())/(gzdUtmNW.y()-gzdUtmSW.y());
xlimit = gzdUtmSW.x() + r * (gzdUtmNW.x() - gzdUtmSW.x());
if ( nw.x() < xlimit ) nw.x() = xlimit;
osg::Vec3d se(utmEx.xMax(), utmEx.yMin(), 0);
//.........这里部分代码省略.........