osgEarth的Rex引擎原理分析(一二六)rex瓦片组织方式

Posted hankern

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了osgEarth的Rex引擎原理分析(一二六)rex瓦片组织方式相关的知识,希望对你有一定的参考价值。

目标:(一二五)中问题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&amp;x=x&amp;y=y&amp;z=z&amp;styles=pl&amp;udt=20171031&amp;scaler=1&amp;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>

 

osgEarth/ImageLayer.cpp
GeoImage
ImageLayer::assembleImage(const TileKey& key, ProgressCallback* progress)

    // If we got here, asset that there's a non-null layer profile.
    if (!getProfile())
    
        setStatus(Status::Error(Status::AssertionFailure, "assembleImage with undefined profile"));
        return GeoImage::INVALID;
    

    GeoImage mosaicedImage, result;

    // Scale the extent if necessary to apply an "edge buffer"
    GeoExtent ext = key.getExtent();
    if ( options().edgeBufferRatio().isSet() )
    
        double ratio = options().edgeBufferRatio().get();
        ext.scale(ratio, ratio);
    

    // Get a set of layer tiles that intersect the requested extent.
    std::vector<TileKey> intersectingKeys;
    getProfile()->getIntersectingTiles( key, intersectingKeys );

    if ( intersectingKeys.size() > 0 )
    
        double dst_minx, dst_miny, dst_maxx, dst_maxy;
        key.getExtent().getBounds(dst_minx, dst_miny, dst_maxx, dst_maxy);

        // if we find at least one "real" tile in the mosaic, then the whole result tile is
        // "real" (i.e. not a fallback tile)
        bool retry = false;
        ImageMosaic mosaic;

        // keep track of failed tiles.
        std::vector<TileKey> failedKeys;

        for( std::vector<TileKey>::iterator k = intersectingKeys.begin(); k != intersectingKeys.end(); ++k )
        
            GeoImage image = createImageImplementation( *k, progress );

            if ( image.valid() )
            
                if ( !isCoverage() )
                
                    ImageUtils::fixInternalFormat(image.getImage());

                    // Make sure all images in mosaic are based on "RGBA - unsigned byte" pixels.
                    // This is not the smarter choice (in some case RGB would be sufficient) but
                    // it ensure consistency between all images / layers.
                    //
                    // The main drawback is probably the CPU memory foot-print which would be reduced by allocating RGB instead of RGBA images.
                    // On GPU side, this should not change anything because of data alignements : often RGB and RGBA textures have the same memory footprint
                    //
                    if (   (image.getImage()->getDataType() != GL_UNSIGNED_BYTE)
                        || (image.getImage()->getPixelFormat() != GL_RGBA) )
                    
                        osg::ref_ptr<osg::Image> convertedImg = ImageUtils::convertToRGBA8(image.getImage());
                        if (convertedImg.valid())
                        
                            image = GeoImage(convertedImg.get(), image.getExtent());
                        
                    
                

                mosaic.getImages().push_back( TileImage(image.getImage(), *k) );
            
            else
            
                // the tile source did not return a tile, so make a note of it.
                failedKeys.push_back( *k );

                if (progress && (progress->isCanceled() || progress->needsRetry()))
                
                    retry = true;
                    break;
                
            
        

        if ( mosaic.getImages().empty() || retry )
        
            // if we didn't get any data, fail.
            OE_DEBUG << LC << "Couldn't create image for ImageMosaic " << std::endl;
            return GeoImage::INVALID;
        

        // We got at least one good tile, so go through the bad ones and try to fall back on
        // lower resolution data to fill in the gaps. The entire mosaic must be populated or
        // this qualifies as a bad tile.
        for(std::vector<TileKey>::iterator k = failedKeys.begin(); k != failedKeys.end(); ++k)
        
            GeoImage image;

            for(TileKey parentKey = k->createParentKey();
                parentKey.valid() && !image.valid();
                parentKey = parentKey.createParentKey())
            
                image = createImageImplementation( parentKey, progress );
                if ( image.valid() )
                
                    GeoImage cropped;

                    if ( !isCoverage() )
                    
                        ImageUtils::fixInternalFormat(image.getImage());
                        if (   (image.getImage()->getDataType() != GL_UNSIGNED_BYTE)
                            || (image.getImage()->getPixelFormat() != GL_RGBA) )
                        
                            osg::ref_ptr<osg::Image> convertedImg = ImageUtils::convertToRGBA8(image.getImage());
                            if (convertedImg.valid())
                            
                                image = GeoImage(convertedImg.get(), image.getExtent());
                            
                        

                        cropped = image.crop( k->getExtent(), false, image.getImage()->s(), image.getImage()->t() );
                    

                    else
                    
                        // TODO: may not work.... test; tilekey extent will <> cropped extent
                        cropped = image.crop( k->getExtent(), true, image.getImage()->s(), image.getImage()->t(), false );
                    

                    // and queue it.
                    mosaic.getImages().push_back( TileImage(cropped.getImage(), *k) );       

                
            

            if ( !image.valid() )
            
                // a tile completely failed, even with fallback. Eject.
                OE_DEBUG << LC << "Couldn't fallback on tiles for ImageMosaic" << std::endl;
                // let it go. The empty areas will be filled with alpha by ImageMosaic.
            
        

        // all set. Mosaic all the images together.
        double rxmin, rymin, rxmax, rymax;
        mosaic.getExtents( rxmin, rymin, rxmax, rymax );

        mosaicedImage = GeoImage(
            mosaic.createImage(),
            GeoExtent( getProfile()->getSRS(), rxmin, rymin, rxmax, rymax ) );
    
    else
    
        OE_DEBUG << LC << "assembleImage: no intersections (" << key.str() << ")" << std::endl;
    

    // Final step: transform the mosaic into the requesting key's extent.
    if ( mosaicedImage.valid() )
    
        // GeoImage::reproject() will automatically crop the image to the correct extents.
        // so there is no need to crop after reprojection. Also note that if the SRS's are the 
        // same (even though extents are different), then this operation is technically not a
        // reprojection but merely a resampling.

        result = mosaicedImage.reproject( 
            key.getProfile()->getSRS(),
            &key.getExtent(), 
            options().reprojectedTileSize().get(),
            options().reprojectedTileSize().get(),
            options().driver()->bilinearReprojection().get());
    

    // Process images with full alpha to properly support MP blending.
    if (result.valid() && 
        options().featherPixels() == true &&
        isCoverage() == false)
    
        ImageUtils::featherAlphaRegions( result.getImage() );
    

    return result;

1、初始第0级,横向2个,纵向1个,是硬编码在程序中的,不可更改。(是可以更改的,不可更改的原因是因为这是创建了一个命名的Profile,如果定制开发就可以参考Profile::create)(osgEarth的Rex引擎原理分析(二十九)osgEarth::Map的Profile创建过程_hankern的博客-CSDN博客目标:(二十)中的问题63osgEarth::Profile定义了地理信息数据源的组织方式,包括参考坐标系、在参考坐标系下地理信息范围、瓦片分片方案等。Profile翻译为地理信息参数配置文件比较合适。在Map添加图层ImageLayer时会创建瓦片源TileSource,瓦片源又会创建Profile,最后将此Profile赋给ImageLayer,但是并没有设置Map的Profile...https://blog.csdn.net/hankern/article/details/84500491

osgEarth/Registry.cpp
const Profile*
Registry::getGlobalGeodeticProfile() const

    if ( !_global_geodetic_profile.valid() )
    
        GDAL_SCOPED_LOCK;

        if ( !_global_geodetic_profile.valid() ) // double-check pattern
        
            const_cast<Registry*>(this)->_global_geodetic_profile = Profile::create(
                "epsg:4326",
                -180.0, -90.0, 180.0, 90.0,
                "",
                2, 1 );
        
    
    return _global_geodetic_profile.get();

<image name="mapbox_satellite" driver="xyz">
        <url>http://online2.map.bdimg.com/tile/?qt=tile&amp;x=x&amp;y=y&amp;z=z&amp;styles=pl&amp;udt=20171031&amp;scaler=1&amp;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>1</num_tiles_wide_at_lod_0>
			  	<num_tiles_high_at_lod_0>1</num_tiles_high_at_lod_0>  
        </profile>             
	  </image>
osgEarth/Profile.cpp
const Profile*
Profile::create( const ProfileOptions& options )

    const Profile* result = 0L;

    // Check for a "well known named" profile:
    if ( options.namedProfile().isSet() )
    
        result = Profile::createNamed(options.namedProfile().get());
    

    // Next check for a user-defined extents:
    else if ( options.srsString().isSet() && options.bounds().isSet() )
    
        if ( options.numTilesWideAtLod0().isSet() && options.numTilesHighAtLod0().isSet() )
        
            result = Profile::create(
                options.srsString().value(),
                options.bounds()->xMin(),
                options.bounds()->yMin(),
                options.bounds()->xMax(),
                options.bounds()->yMax(),
                options.vsrsString().value(),
                options.numTilesWideAtLod0().value(),
                options.numTilesHighAtLod0().value() );
        
        else
        
            result = Profile::create(
                options.srsString().value(),
                options.bounds()->xMin(),
                options.bounds()->yMin(),
                options.bounds()->xMax(),
                options.bounds()->yMax(),
                options.vsrsString().value() );
        
    

    // Next try SRS with default extents
    else if ( options.srsString().isSet() )
    
        if ( options.numTilesWideAtLod0().isSet() && options.numTilesHighAtLod0().isSet() )
        
            result = Profile::create(
                options.srsString().value(),
                options.vsrsString().value(),
                options.numTilesWideAtLod0().value(),
                options.numTilesHighAtLod0().value() );
        
        else
        
            result = Profile::create(
                options.srsString().value(),
                options.vsrsString().value() );
        
    

    return result;

待继续分析列表:

9、earth文件中都有哪些options((九)中问题)

10、如何根据earth文件options创建不同的地理信息引擎节点((九)中问题)

11、rex地理信息引擎的四梁八柱((九)中问题)

12、osgEarth::TerrainEngineNode中setMap方法作用((十二)中问题)

13、RexTerrainEngineNode中_mapFrame的作用((十二)中问题)

14、地形变形(Terrain morphing)((十二)中问题)

15、地球瓦片过期门限的含义((十二)中问题)

16、高分辨率优先的含义((十二)中问题)

17、OSGEARTH_DEBUG_NORMALS环境变量的作用((十二)中问题)

18、活跃瓦片寄存器的作用((十二)中问题)

19、资源释放器子节点的作用((十二)中问题)

20、共享几何图形池子节点的作用((十二)中问题)

21、分页瓦片加载器子节点的作用((十二)中问题)

22、分页瓦片卸载器子节点的作用((十二)中问题)

23、栅格化器子节点的作用((十二)中问题)

24、地形子节点的作用((十二)中问题)

25、绑定渲染器的作用((十二)中问题)

26、地图回调函数的作用((十二)中问题)

27、如何将地图图层添加到rex引擎中((十二)中问题)

28、选择信息的作用((十二)中问题)

29、瓦片包围盒修改回调函数的作用((十二)中问题)

30、刷新rex引擎((十二)中问题)

31、刷新边界作用((十二)中问题)

32、osgEarth::Metrics类的意义((十四)中问题)

33、请求合并队列_mergeQueue((十四)中问题)

34、分页瓦片加载器在更新遍历时对请求处理过程((十四)中问题)

35、分页瓦片加载器在更新遍历时对已处理请求裁剪过程((十四)中问题)

36、已处理的请求队列_requests((十四)中问题)

37、DatabasePager中的_fileRequestQueue和_httpRequestQueue((十六)中问题)

38、瓦片请求的生成到处理过程详解((十六)中问题)

39、瓦片节点TileNode的创建过程((十七)中问题)

40、request请求加载瓦片优先级的含义((十七)中问题)

41、request的_internalHandle的作用((十七)中问题)

42、DatabaseRequest中_objectCache含义((十七)中问题)

42、osgEarth的多线程分析((十七)中问题)

43、osgEarth的缓存及其结构((十七)中问题)

44、DatabaseThread从缓存加载数据过程((十七)中问题)

45、DatabaseThread从文件加载数据过程((十七)中问题)

46、决定创建TileNode的时机条件((十七)中问题)

47、TerrainEngineNode的createTileModel过程详解((十七)中问题)

48、DatabaseThread中CompileSet的含义((十七)中问题)

48、PagerLoader的traverse过程详解((十七)中问题)

49、DatabaseThread的run过程详解((十七)中问题)

50、LoadTileData的invoke过程详解((十七)中问题)

51、TileNode的cull过程详解((十七)中问题)

52、遮罩生成器osgEarth::Drivers::RexTerrainEngine::MaskGenerator((十八)中问题)

53、RexTerrainEngineNode::traverse过程详解((十八)中问题)

54、TileNode节点下的场景树分析((十八)中问题)

55、地形瓦片大小尺寸和LOD的关系((十八)中问题)

56、TileNode的_tileKeyValue作用((十八)中问题)

57、TileNode的_morphConstants作用((十八)中问题)

58、TileNode的_stitchNormalMap作用((十八)中问题)

59、TileNode的_renderModel作用((十八)中问题)

60、初始化高程栅格过程详解((十八)中问题)

61、LoadTileData中的CreateTileModelFilter作用((十八)中问题)

62、TileNode节点何时会从场景树中移除((十八)中问题)

63、osgEarth::Map的Profile创建过程((二十)中问题)

64、osgEarth::TerrainTileModelFactory添加颜色层和影像层的区别((二十一)中问题)

65、osgEarth::PatchLayer修补层的作用((二十一)中问题)

66、osgEarth::TerrainLayer中的_memCache(osgEarth::MemCache)详解((二十一)中问题)

67、osgEarth::Layer::RenderType图层渲染类型的作用((二十一)中问题)

68、osgEarth::TerrainLayer中TileSource的作用((二十一)中问题)

69、earth文件没有设置高程图层会不会有默认高程层(高程均为0)((二十一)中问题)

70、TerrainTileModelFactory::addColorLayers过程详解((二十一)中问题)

71、TerrainTileModelFactory::addElevation过程详解((二十一)中问题)

72、osgearth中可能用到的几个全局实例对象(osgDB::Registry osgEarth::Registry osg::Timer osg::DisplaySetting)((二十三)中问题)

73、osgEarth::Map::addLayer过程详解((二十三)中问题)

74、TileNode::setDirty过程详解((二十三)中问题)

75、请求四个状态的含义(IDLE RUNNING MERGING FINISHED)((二十三)中问题)

76、什么时候删除TileNode节点,不会一直增加吧((二十三)中问题)

77、寄存器中请求状态活动记录的含义Registry::instance()->endActivity( req->getName() )((二十三)中问题)

78、瓦片TileNode的生命周期流程详解((二十三)中问题)

79、rex引擎如何将瓦片构造成地球形状((二十五)中问题)

80、高程、影像文件格式详解((二十五)中问题)

81、TileNode的merge过程详解((二十六)中问题)

82、osgEarth支持的空间参考坐标系详解(osgEarth::SpatialReference、osgEarth::CubeSpatialReference、osgEarth::TangentPlaneSpatialReference)((二十九)中问题)

83、osgEarth地球椭球体ellipsoid 大地基准面datum 地图投影Projection详解((二十九)中问题)

84、空间参考坐标系和坐标系统类型的关系(geocentric projected)((二十九)中问题)

85、proj4是什么((二十九)中问题)

86、为什么要删除设置过的垂直水准面((二十九)中问题)

87、osgEarth如何对投影坐标系和大地坐标系进行显示处理的((二十九)中问题)

88、TileNode的节点构成,一个surface、tilenode((三十)中问题)

89、MapFram和MapInfo的关系((三十)中问题)

90、ModifyBoundingBoxCallback的使用时机和场合((三十)中问题)

91、MapFrame为什么要单独存放高程层_elevationLayers,而不是放在图层_layers中((三十)中问题)

92、MapFrame和Map中高程池的作用osg::ref_ptr<ElevationPool> _elevationPool((三十)中问题)

93、osgEarth::Drivers::RexTerrainEngine::TileDrawable分析((三十)中问题)

94、请求读取地理信息失败会如何处理((三十二)中问题)

95、RexTerrainEngineNode的遍历过程详解((三十三)中问题)

96、osgEarth::Drivers::RexTerrainEngine::TerrainCuller的apply过程详解((三十三)中问题)

97、RexTerrainEngineNode的updateState过程详解 设置了很多着色器变量((三十三)中问题)

98、什么时候分配opengl资源((三十三)中问题)

99、TileNode释放opengl资源过程releaseGLObjects详解((三十三)中问题)

100、最近一次遍历的帧号和时间是怎么设置呢(在渲染遍历里),怎么就不会再渲染遍历该瓦片节点了((三十三)中问题)

101、osg::State和osg::StateSet的关系((三十四)中问题)

102、osgEarth::SpatialReference和osgEarth::Profile的关系((三十六)中问题)

103、osgEarth的Geographic、Geodetic、Geocentric和Project的关系((三十六)中问题)

104、TileNode绘制过程详解((三十七)中问题)

105、如何控制父子TileNode节点的显隐((三十七)中问题)

106、GeometryPool的createGeometry过程详解((三十七)中问题)

107、TileNode如何从地图中提取与其分辨率相适应的图像数据((三十七)中问题)

108、如何定制椭球体并进行椭球体间坐标转换((四十五)中问题)

109、Horizon Cull是什么意思((四十五)中问题)

110、osgEarth::Drivers::RexTerrainEngine::DrawState的作用((四十五)中问题)

111、osgEarth的线程分析((四十五)中问题)

112、从osgEarth到osg到Opengl((四十五)中问题)

113、osg::Program与osgEarth::VirtualProgram的关系((四十五)中问题)

114、rex引擎shader文件中的#pragma vp_entryPoint vp_location等含义((四十五)中问题)

115、rex引擎的着色器如何区分顶点和片段((四十五)中问题)

116、osg::Program是如何对着色器及其变量进行管理的((四十五)中问题)

117、osg的窗口是如何与opengl集成的((四十五)中问题)

118、osg是如何实现opengl的初始化的((四十五)中问题)

119、CGCS2000余WGS84坐标系的比较((四十六)中问题)

120、着色器代码文件到着色器程序的过程((五十一)中问题)

121、osgEarth::VirtualProgram默认出现在哪些位置((五十一)中问题)

122、rex引擎默认的几个着色器功能分析((五十一)中问题)

123、osgEarth::TileRasterizer功能详解((五十二)中问题)

124、osgEarth::ImageLayer如何使用VirtualProgram((五十二)中问题)

125、osgEarth::ShaderFactory osgEarth::ShaderLoader关系((五十四)中问题)

126、osgEarth::URI和osgEarth::URIContext的作用((五十四)中问题)

127、RexTerrainEngineNode中_renderBindings的作用((五十四)中问题)

128、Rex引擎如何给shader文件中的uniform变量赋值((五十四)中问题)

129、osgEarth中多个着色器的源代码的编译链接过程((五十四)中问题)

130、osgEarth::ShaderFactory osgEarth::ShaderLoader关系((五十四)中问题)

131、TileNode与DrawTileCommand的关系((五十五)中问题)

132、如何提取出指定范围的高程网格((五十五)中问题)

133、从earth文件加载高层图层的过程((五十五)中问题)

134、TerrainTileModel与TileRenderModel的关系((五十五)中问题)

135、EngineContext的作用((五十五)中问题)

136、几个uniformmap的关系((五十五)中问题)

137、DrawTileCommand中的采样器((五十五)中问题)

138、TileNode中的_surface(SurfaceNode)作用是什么((五十五)中问题)

139、stateset中的adduniform、setTextureAttribute等最后是如何反应到opengl上的((五十五)中问题)

140、状态树和渲染树的关系((五十五)中问题)

141、TileRenderModel中的RenderingPass和RenderBindings((五十五)中问题)

142、高程瓦片的绘制过程((五十五)中问题)

143、如何从高程影像变成高程网格((七十一)中问题)

144、osg::StateSet中的_binMode作用((七十二)中问题)

145、rex的瓦片高程影像和高程文件中的影像尺寸如何对应((七十二)中问题)

146、osgEarth::TerrainLayerOptions高程层选项中参数的含义((七十二)中问题)

147、从高程文件读取的高程信息如何填充rex的高程瓦片((七十二)中问题)

148、地图下载器实现原理((七十二)中问题)

149、RexTerrainEngineNode和TerrainCuller中_terrain的关系((七十二)中问题)

150、TileNodeRegistry和LayerDrawable中_tiles的关系((七十二)中问题)

151、rex引擎中绘制瓦片的调度过程原理((七十二)中问题)

152、晕眩图的制作与实现((七十八)中问题)

153、如何将高层场保存为tif、MBTiles等((七十八)中问题)

154、如何将tif和MBTiles进行格式转换((七十八)中问题)

155、如何加载百度、高德、谷歌、微软的在线地图((七十八)中问题)

156、osgEarth运行起来为什么很占CPU资源((七十九)中问题)

157、wmts与xyz、quadtree、tms的关系((七十九)中问题)

158、获取的高程图像为什么除了设置纹理还要设置栅格((八十)中问题)

159、rex引擎创建图层的过程((八十一)中问题)

160、如何设置高度单位(m、km等)((八十二)中问题)

161、网络资源加载失败还会不会继续加载((八十二)中问题)

162、rex引擎打开图层的过程((八十二)中问题)

163、osgEarth::MemCache详解((八十二)中问题)

164、OGR与GDAL的关系((八十二)中问题)

165、osgEarth::Map的cache创建过程((八十三)中问题)

166、osgEarth跨平台的头文件包含设置((八十三)中问题)

167、rex引擎如何实现淹没分析((八十八)中问题)

168、rex引擎如何实现挖方分析((八十八)中问题)

169、rex引擎如何实现地形整平((八十八)中问题)

170、rex引擎如何绘制矢量图形((八十八)中问题)

170、rex引擎如何绘制等高线((八十八)中问题)

171、rex引擎如何显示瓦片的边界((八十八)中问题)

172、边界处瓦片颜色混合的实现((九十)中问题)

173、rex自带的着色器代码会硬编码进动态库吗((九十一)中问题)

174、rex在渲染时会不会纹理单元内容频繁更改((九十一)中问题)

175、如何显示瓦片编号((九十四)中问题)

176、缓存文件复用、弃用的判决((九十五)中问题)

177、RenderingPasses和RenderBindings((九十五)中问题)

178、如何定义裸球颜色并在绘制时起作用((九十八)中问题)

179、有影像和无影像的瓦片在一起如何保证无影像的瓦片被绘制((九十九)中问题)

180、如何判断瓦片的添加删除((一零零)中问题)

181、TileNode::merge为什么只是不合并最后一个图层((一零零)中问题)

182、ImageLayer的coverage属性含义((一零一)中问题)

183、如何判断图源支持的最大级别((一零一)中问题)

184、着色器如何绘制文字((一零一)中问题)

185、rex如何将文字生成图片((一零一)中问题)

186、rex如何在地球上绘制一张图片((一零三)中问题)

187、如何将文字变为图片((一零四)中问题)

188、rex下各个文件、类介绍((一零五)中问题)

189、术语定义((一零五)中问题)

190、rex的状态树和渲染树((一零六)中问题)

191、章节目录((一零七)中问题)

192、雾化fog效果((一零八)中问题)

193、云的渲染((一零八)中问题)

194、19级瓦片分辨率估算((一零八)中问题)

195、state中_defineMap构建过程((一零九)中问题)

196、state获取着色器文件中有效define的过程((一零九)中问题)

197、着色器上下文环境的准备过程((一一零)中问题)

198、每帧会重复生成着色器程序吗(一一一)

199、重复加载着色器文件对最终程序的影响(一一三)

200、如何让地球显的更有质感(一一三)

201、rex与mp引擎的关系(一一三)

202、tif文件分辨率的计算(一一四)

203、地理数据坐标系分类(一一五)

204、无法加载部分tif文件的原因(一一六)

205、_tileKeyValue的设置为什么使用fmod(一一八)

206、为什么rex的瓦片分级为21级,Google为23级(一一八)

207、renderinfo的作用(一二零)

208、着色器程序的opengl过程(一二一)

209、实现wmts插件(一二三)

210、osgEarth着色器文件与场景树节点的对应关系(一二三)

211、着色器源代码加工处理过程(一二四)

212、rex瓦片组织方式(一二五)

213、rex影像层属性及其设置(一二六)

以上是关于osgEarth的Rex引擎原理分析(一二六)rex瓦片组织方式的主要内容,如果未能解决你的问题,请参考以下文章

osgEarth的Rex引擎原理分析(一二七)rex影像层属性及其设置

osgEarth的Rex引擎原理分析(一二七)rex影像层属性及其设置

osgEarth的Rex引擎原理分析(一二三)osgEarth的缓存及其结构

osgEarth的Rex引擎原理分析(一二八)rex的引擎和图层投影及其关系

osgEarth的Rex引擎原理分析(一二八)rex的引擎和图层投影及其关系

osgEarth的Rex引擎原理分析(一二五)着色器源代码加工处理过程