HOW TO : Manage Large Feature Datasets
The simplest way to load feature data into osgEarth is like this:
<model name="shapes">
<features name="data" driver="ogr">
<url>data.shp</url>
</features>
<styles>
data {
fill: #ffff00;
}
</styles>
</model>
We just loaded every feature in the shapefile and colored them all yellow.
This works fine up to a point -- the point at which osgEarth (and OSG) become overloaded with too much geometry. Even with the optimizations that osgEarth's geometry compiler employs, a large enough dataset can exhaust system resources.
The solution to that is feature tiling and paging. Here is how to configure it.
Feature Display Layout
The feature display layout activates paging and tiles of feature data. Let's modify the previous example:
<model name="shapes">
<features name="data" driver="ogr">
<url>data.shp</url>
</features>
<layout>
<tile_size_factor>15.0</tile_size_factor>
<level name="only" max_range="100000"/>
</layout>
<styles>
data {
fill: #ffff00;
}
</styles>
</model>
The mere presence of the <layout> element activates paging. This means that instead of being loaded and compiled at load time, the feature data will load and compile in the background once the application has started. There may be a delay before the feature data shows up in the scene, depending on its complexity.
The presence of <level> elements within the layout actives tiling and levels of detail. If you OMIT levels, the data will still load in the background, but it will all load at once. With one or more levels, osgEarth will break up the feature data into tiles at one or more levels of detail and page those tiles in individually. More below.
Levels
Each level describes a level of detail. This is a camera range (between min_range and max_range) at which tiles in this level of detail are rendered. But how big is each tile? This is calculated based on the tile range factor.
The tile_range_factor determines the size of a tile, based on the max_range of the LOD. The tile range factor is the multiple of a tile's radius at which the LOD's max_range takes effect. In other words:
tile radius = max range / tile size factor.
The default tile range factor is 15.0.
The upshot is: if you want larger tiles, reduce the range factor. For smaller tiles, increase the factor.
Why do you care about tile size? Because the density of your data will affect how much geometry is in each tile. And since OSG (OpenGL, really) benefits from sending large batches of similar geometry to the graphics card, tweaking the tile size can help with performance and throughput. Unfortunately there's no way for osgEarth to know exactly what the "best" tile size will be in advance; so, you have the opportunity to tweak using this setting.
Multiple Levels and Using Selectors
You can have any number of levels -- but keep in mind that unlike the terrain imagery, feature data does NOT form a quadtree in which the higher LODs replace the lower ones. Rather, feature levels are independent of one another. So if you want to draw more detail as you zoom in closer, you have to use selectors to decide what you want to draw at each step.
Here's an example. Say we're drawing roads. We have a shapefile in which the road type is stored in an attribute called "roadtype":
<layout>
<tile_size_factor>15.0</tile_size_factor>
<crop_features>true</crop_features>
<level name="highway" max_range="100000">
<selector class="highway">
<query>
<expr>roadtype = 'A'</expr>
</query>
</selector>
</level>
<level name="street" max_range="10000">
<selector class="street">
<query>
<expr>roadtype = 'B'</expr>
</query>
</selector>
</level>
</layout>
<styles>
highway {
stroke: #ffff00;
stroke-width: 2.0;
}
street {
stroke: #ffffff7f;
stroke-width: 1.0;
}
</styles>
