目标:(一二五)中问题212
通过如下确定瓦片的组织方式 ,核心是profile
osgEarth/Map.cpp
void
Map::calculateProfile()
{
// collect the terrain layers; we will need them later
TerrainLayerVector layers;
getLayers(layers);
// Figure out the map profile:
if ( !_profile.valid() )
{
osg::ref_ptr<const Profile> profile;
// Do the map options contain a profile? If so, try to use it:
if ( _mapOptions.profile().isSet() )
{
profile = Profile::create( _mapOptions.profile().value() );
}
// Do the map options contain an override coordinate system type?
// If so, attempt to apply that next:
if (_mapOptions.coordSysType().isSetTo(MapOptions::CSTYPE_GEOCENTRIC))
{
if (profile.valid() && profile->getSRS()->isProjected())
{
OE_WARN << LC << "Geocentric map type conflicts with the projected SRS profile; ignoring your profile\n";
profile = Registry::instance()->getGlobalGeodeticProfile();
}
}
// Do the map options ask for a projected map?
else if (_mapOptions.coordSysType().isSetTo(MapOptions::CSTYPE_PROJECTED))
{
// Is there a conflict in the MapOptions?
if (profile.valid() && profile->getSRS()->isGeographic())
{
OE_WARN << LC << "Projected map type conflicts with the geographic SRS profile; converting to Equirectangular projection\n";
unsigned u, v;
profile->getNumTiles(0, u, v);
const osgEarth::SpatialReference* eqc = profile->getSRS()->createEquirectangularSRS();
osgEarth::GeoExtent e = profile->getExtent().transform( eqc );
profile = osgEarth::Profile::create( eqc, e.xMin(), e.yMin(), e.xMax(), e.yMax(), u, v);
}
// Is there no profile set? Try to derive it from the Map layers:
if (!profile.valid())
{
for (TerrainLayerVector::iterator i = layers.begin(); !profile.valid() && i != layers.end(); ++i)
{
profile = i->get()->getProfile();
}
}
if (!profile.valid())
{
OE_WARN << LC << "No profile information available; defaulting to Spherical Mercator projection\n";
profile = Registry::instance()->getSphericalMercatorProfile();
}
}
// Finally, if there is still no profile, default to global geodetic.
if (!profile.valid())
{
profile = Registry::instance()->getGlobalGeodeticProfile();
}
// Set the map's profile!
_profile = profile.release();
// create a "proxy" profile to use when querying elevation layers with a vertical datum
if ( _profile->getSRS()->getVerticalDatum() != 0L )
{
ProfileOptions po = _profile->toProfileOptions();
po.vsrsString().unset();
_profileNoVDatum = Profile::create(po);
}
else
{
_profileNoVDatum = _profile;
}
// finally, fire an event if the profile has been set.
OE_INFO << LC << "Map profile is: " << _profile->toString() << std::endl;
for( MapCallbackList::iterator i = _mapCallbacks.begin(); i != _mapCallbacks.end(); i++ )
{
i->get()->onMapInfoEstablished( MapInfo(this) );
}
}
// Tell all the layers about the profile
for (TerrainLayerVector::iterator i = layers.begin(); i != layers.end(); ++i)
{
if (i->get()->getEnabled())
{
i->get()->setTargetProfileHint(_profile.get());
}
}
}
profile在earth文件中的设置如下
<options>
<profile>
<srs>epsg:4326</srs>
<xmin>-180.0</xmin>
<ymin>-90.0</ymin>
<xmax>180.0</xmax>
<ymax>90.0</ymax>
<num_tiles_wide_at_lod_0>1</num_tiles_wide_at_lod_0>
<num_tiles_high_at_lod_0>1</num_tiles_high_at_lod_0>
</profile>
</options>
可设置的属性如下
class OSGEARTH_EXPORT ProfileOptions : public ConfigOptions
{
optional<std::string> _namedProfile;
optional<std::string> _srsInitString;
optional<std::string> _vsrsInitString;
optional<Bounds> _bounds;
optional<int> _numTilesWideAtLod0;
optional<int> _numTilesHighAtLod0;
};
osgEarth/Profile.cpp
void
ProfileOptions::fromConfig( const Config& conf )
{
if ( !conf.value().empty() )
_namedProfile = conf.value();
conf.getIfSet( "srs", _srsInitString );
conf.getIfSet( "vdatum", _vsrsInitString );
conf.getIfSet( "vsrs", _vsrsInitString ); // back compat
if ( conf.hasValue( "xmin" ) && conf.hasValue( "ymin" ) && conf.hasValue( "xmax" ) && conf.hasValue( "ymax" ) )
{
_bounds = Bounds(
conf.value<double>( "xmin", 0 ),
conf.value<double>( "ymin", 0 ),
conf.value<double>( "xmax", 0 ),
conf.value<double>( "ymax", 0 ) );
}
conf.getIfSet( "num_tiles_wide_at_lod_0", _numTilesWideAtLod0 );
conf.getIfSet( "num_tiles_high_at_lod_0", _numTilesHighAtLod0 );
}
以上为Map下的profile,在image下也有profile,它们是有关系的,主要体现在intersectingKeys上,一般将这两个profile设置成一样的。
<image name="mapbox_satellite" driver="xyz">
<url>http://online2.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=pl&udt=20171031&scaler=1&p=1</url>
<profile>
<srs>epsg:4326</srs>
<xmin>-180.0</xmin>
<ymin>-90.0</ymin>
<xmax>180.0</xmax>
<ymax>90.0</ymax>
<num_tiles_wide_at_lod_0>2</num_tiles_wide_at_lod_0>
<num_tiles_high_at_lod_0>2</num_tiles_high_at_lod_0>
</profile>
</image>