void updateControlPanel() { // erase all child controls and just rebuild them b/c we're lazy. //Rebuild all the image layers s_imageBox->clearControls(); int row = 0; LabelControl* activeLabel = new LabelControl( "Image Layers", 20, osg::Vec4f(1,1,0,1) ); s_imageBox->setControl( 1, row++, activeLabel ); // the active map layers: MapFrame mapf( s_activeMap.get() ); ImageLayerVector imageLayers; mapf.getLayers(imageLayers); int layerNum = imageLayers.size()-1; for( ImageLayerVector::const_reverse_iterator i = imageLayers.rbegin(); i != imageLayers.rend(); ++i ) createLayerItem( s_imageBox, row++, layerNum--, imageLayers.size(), i->get(), true ); MapFrame mapf2( s_inactiveMap.get() ); imageLayers.clear(); mapf2.getLayers(imageLayers); if ( imageLayers.size() > 0 ) { LabelControl* inactiveLabel = new LabelControl( "Removed:", 18, osg::Vec4f(1,1,0,1) ); s_imageBox->setControl( 1, row++, inactiveLabel ); for( unsigned int i=0; i<imageLayers.size(); ++i ) { createLayerItem( s_imageBox, row++, -1, -1, imageLayers[i].get(), false ); } } //Rebuild the elevation layers s_elevationBox->clearControls(); row = 0; activeLabel = new LabelControl( "Elevation Layers", 20, osg::Vec4f(1,1,0,1) ); s_elevationBox->setControl( 1, row++, activeLabel ); // the active map layers: ElevationLayerVector elevationLayers; mapf.getLayers(elevationLayers); layerNum = elevationLayers.size()-1; for( ElevationLayerVector::const_reverse_iterator i = elevationLayers.rbegin(); i != elevationLayers.rend(); ++i ) createLayerItem( s_elevationBox, row++, layerNum--, elevationLayers.size(), i->get(), true ); if ( mapf2.elevationLayers().size() > 0 ) { LabelControl* inactiveLabel = new LabelControl( "Removed:", 18, osg::Vec4f(1,1,0,1) ); s_elevationBox->setControl( 1, row++, inactiveLabel ); for( unsigned int i=0; i<mapf2.elevationLayers().size(); ++i ) { createLayerItem( s_elevationBox, row++, -1, -1, mapf2.elevationLayers().at(i), false ); } } //Rebuild the model layers s_modelBox->clearControls(); row = 0; activeLabel = new LabelControl( "Model Layers", 20, osg::Vec4f(1,1,0,1) ); s_modelBox->setControl( 1, row++, activeLabel ); // the active map layers: ModelLayerVector modelLayers; mapf.getLayers(modelLayers); for( ModelLayerVector::const_reverse_iterator i = modelLayers.rbegin(); i != modelLayers.rend(); ++i ) createModelLayerItem( s_modelBox, row++, i->get(), true ); }
bool ElevationLayerVector::populateHeightField(osg::HeightField* hf, const TileKey& key, const Profile* haeProfile, ElevationInterpolation interpolation, ProgressCallback* progress ) const { // heightfield must already exist. if ( !hf ) return false; // if the caller provided an "HAE map profile", he wants an HAE elevation grid even if // the map profile has a vertical datum. This is the usual case when building the 3D // terrain, for example. Construct a temporary key that doesn't have the vertical // datum info and use that to query the elevation data. TileKey keyToUse = key; if ( haeProfile ) { keyToUse = TileKey(key.getLOD(), key.getTileX(), key.getTileY(), haeProfile ); } // Collect the valid layers for this tile. ElevationLayerVector contenders; ElevationLayerVector offsets; for(ElevationLayerVector::const_reverse_iterator i = this->rbegin(); i != this->rend(); ++i) { ElevationLayer* layer = i->get(); if ( layer->getEnabled() && layer->getVisible() ) { // calculate the resolution-mapped key (adjusted for tile resolution differential). TileKey mappedKey = keyToUse.mapResolution(hf->getNumColumns(), layer->getTileSize()); // Note: isKeyInRange tests the key, but haData tests the mapped key. // I think that's right! if ((layer->getTileSource() == 0L) || (layer->isKeyInRange(key) && layer->getTileSource()->hasData(mappedKey))) { if (layer->isOffset()) offsets.push_back(layer); else contenders.push_back(layer); } } } // nothing? bail out. if ( contenders.empty() && offsets.empty() ) { return false; } // Sample the layers into our target. unsigned numColumns = hf->getNumColumns(); unsigned numRows = hf->getNumRows(); double xmin = key.getExtent().xMin(); double ymin = key.getExtent().yMin(); double dx = key.getExtent().width() / (double)(numColumns-1); double dy = key.getExtent().height() / (double)(numRows-1); // We will load the actual heightfields on demand. We might not need them all. GeoHeightFieldVector heightFields(contenders.size()); GeoHeightFieldVector offsetFields(offsets.size()); std::vector<bool> heightFailed (contenders.size(), false); std::vector<bool> offsetFailed(offsets.size(), false); const SpatialReference* keySRS = keyToUse.getProfile()->getSRS(); bool realData = false; for (unsigned c = 0; c < numColumns; ++c) { double x = xmin + (dx * (double)c); for (unsigned r = 0; r < numRows; ++r) { double y = ymin + (dy * (double)r); // Collect elevations from each layer as necessary. bool resolved = false; for(int i=0; i<contenders.size() && !resolved; ++i) { if ( heightFailed[i] ) continue; GeoHeightField& layerHF = heightFields[i]; if ( !layerHF.valid() ) { TileKey mappedKey = keyToUse.mapResolution(hf->getNumColumns(), contenders[i]->getTileSize()); layerHF = contenders[i]->createHeightField(mappedKey, progress); if ( !layerHF.valid() ) { heightFailed[i] = true; continue; } } // If we actually got a layer then we have real data realData = true; float elevation; if (layerHF.getElevation(keySRS, x, y, interpolation, keySRS, elevation) && elevation != NO_DATA_VALUE) { resolved = true; hf->setHeight(c, r, elevation); } } for(int i=offsets.size()-1; i>=0; --i) { if ( offsetFailed[i] ) continue; GeoHeightField& layerHF = offsetFields[i]; if ( !layerHF.valid() ) { TileKey mappedKey = keyToUse.mapResolution(hf->getNumColumns(), offsets[i]->getTileSize()); layerHF = offsets[i]->createHeightField(mappedKey, progress); if ( !layerHF.valid() ) { offsetFailed[i] = true; continue; } } // If we actually got a layer then we have real data realData = true; float elevation = 0.0f; if (layerHF.getElevation(keySRS, x, y, interpolation, keySRS, elevation) && elevation != NO_DATA_VALUE) { hf->getHeight(c, r) += elevation; } } } } // Return whether or not we actually read any real data return realData; }