imageroverlay示例,在地球上贴图,并且添加控制面板,控制面板上有:mini图标、复选框(控制图片显隐)、图标名称的name、图片的透明度、Edit(控制编辑点的显隐)。
在原有的基础上,本示例又添加了changeImage(更换图片) 和 坐标位置(拖动编辑点,实时更新中心点的坐标)。
执行命令如下。图片参数,直接写入代码中。
osgearth_imageoverlayd.exe earth_image\china-simple.earth
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace osgEarth;
using namespace osgEarth::Annotation;
using namespace osgEarth::Util;
using namespace osgEarth::Util::Controls;
// 布局根结点
static Grid* s_layerBox = NULL;
// 创建布局
osg::Node*
createControlPanel( osgViewer::View* view )
{
ControlCanvas* canvas = ControlCanvas::getOrCreate( view );
// the outer container:
s_layerBox = new Grid();
s_layerBox->setBackColor(0,0,0,0.5);// 设置布局背景色
s_layerBox->setMargin( 10 ); // 外边距
s_layerBox->setPadding( 10 );// 内边距
s_layerBox->setChildSpacing( 10 );// 布局内子类的间距
s_layerBox->setChildVertAlign( Control::ALIGN_CENTER );// 子类水平居中
s_layerBox->setAbsorbEvents( true );// 设置接收事件
s_layerBox->setVertAlign( Control::ALIGN_BOTTOM );// 垂直底部
canvas->addControl( s_layerBox );
return canvas;
}
int
usage( const std::string& msg )
{
OE_NOTICE << msg << std::endl;
OE_NOTICE << "USAGE: osgearth_imageoverlay file.earth" << std::endl;
OE_NOTICE << " --image xmin ymin xmax ymax : An image to overlay and it's bounds" << std::endl;
OE_NOTICE << " --vert : Move individual verts when editing" << std::endl;
return -1;
}
// 透明度控制
struct OpacityHandler : public ControlEventHandler
{
OpacityHandler( ImageOverlay* overlay ) : _overlay(overlay) { }
void onValueChanged( Control* control, float value ) {
_overlay->setAlpha( value );
}
ImageOverlay* _overlay;
};
// checkbox的值更改
struct EnabledHandler : public ControlEventHandler
{
EnabledHandler( ImageOverlay* overlay ) : _overlay(overlay) { }
void onValueChanged( Control* control, bool value ) {
_overlay->setNodeMask( value ? ~0 : 0 );
}
ImageOverlay* _overlay;
};
// label标签编辑事件,滑块右侧的edit的标签,进行编辑点显隐的切换
struct EditHandler : public ControlEventHandler
{
EditHandler( ImageOverlay* overlay, osgViewer::Viewer* viewer, osg::Node* editor) :
_overlay(overlay),
_viewer(viewer),
_editor(editor){ }
void onClick( Control* control, int mouseButtonMask ) {
if (_editor->getNodeMask() != ~0)
{
static_cast(control)->setText( "Finish" );
_editor->setNodeMask(~0);
}
else
{
static_cast(control)->setText( "Edit" );
_editor->setNodeMask(0);
}
}
ImageOverlay* _overlay;
osgViewer::Viewer* _viewer;
osg::Node* _editor;
};
// 获取点击鼠标事件,然后将用image替换原来的图片
struct ChangeImageHandler : public ControlEventHandler
{
ChangeImageHandler( osg::Image* image, ImageOverlay* overlay, ImageControl* preview) :
_image(image),
_overlay(overlay),
_preview(preview){ }
void onClick( Control* control, int mouseButtonMask ) {
_overlay->setImage( _image.get() );
_preview->setImage( _image.get() );
}
ImageOverlay* _overlay;
osg::ref_ptr< osg::Image > _image;
osg::ref_ptr< ImageControl> _preview;
};
// 覆盖图更新位置回调方法
struct UpdateLabelCallback : public ImageOverlay::ImageOverlayCallback
{
UpdateLabelCallback(LabelControl* label, ImageOverlay* overlay, ImageOverlay::ControlPoint controlPoint):
_label(label),
_overlay(overlay),
_controlPoint(controlPoint)
{
}
// 当覆盖图被移动时,会打印输出位置信息到label标签上
virtual void onOverlayChanged()
{
osg::Vec2d location = _overlay->getControlPoint( _controlPoint );
std::stringstream ss;
ss << location.y() << ", " << location.x();
std::string str;
str = ss.str();
_label->setText( str );
}
osg::ref_ptr< LabelControl > _label;
osg::ref_ptr< ImageOverlay > _overlay;
ImageOverlay::ControlPoint _controlPoint;
};
int
main(int argc, char** argv)
{
osg::ArgumentParser arguments(&argc,argv);
// osg::DisplaySettings 封装所需和已设置的视觉效果以及立体观看的状态类
osg::DisplaySettings::instance()->setMinimumNumStencilBits( 8 );
std::vector< std::string > imageFiles;
std::vector< Bounds > imageBounds;
//Read in the image files
// 可以通过命令窗口输入文件路径,图片尺寸,并且尺寸是经纬度
std::string filename;
Bounds bounds;// 继承自包围盒类
while (arguments.read("--image", filename, bounds.xMin(), bounds.yMin(), bounds.xMax(), bounds.yMax()))
{
imageFiles.push_back( filename );
imageBounds.push_back( bounds );
}
//
if (imageFiles.empty())
{
imageFiles.push_back("../data/m2525_air.png");// 仅支持png ,加载gif jpg,会显示黑图
imageBounds.push_back( Bounds(-100, 30, -90, 40) );
// 继续追加一张图
imageFiles.push_back("../data/m2525_air.png");
imageBounds.push_back(Bounds(-120, 30, -110, 40));
}
bool moveVert = arguments.read("--vert");
// load the .earth file from the command line.加载map地图
osg::ref_ptr earthNode = osgDB::readNodeFiles( arguments );
if (!earthNode.valid())
return usage( "Unable to load earth model." );
osgViewer::Viewer viewer(arguments);
// 创建操作器并添加到视景器viewer
EarthManipulator* manip = new EarthManipulator();
viewer.setCameraManipulator( manip );
osg::Group* root = new osg::Group();
root->addChild( earthNode.get() );
//Create the control panel 创建控制面板
root->addChild( createControlPanel(&viewer) );
viewer.setSceneData( root );
// 获取mapNode
osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode( earthNode.get() );
if ( mapNode )
{
// 当处理多张图时,会添加多组控件
for (unsigned int i = 0; i < imageFiles.size(); i++)
{
std::string imageFile = imageFiles[i];
//Read the image file and play it if it's a movie 如果传入的图多个,则读取并播放
osg::ref_ptr image = osgDB::readRefImageFile(imageFile);
if (image.valid())
{
osg::ImageStream* is = dynamic_cast(image.get());
if (is)
{
std::cout << "is->play()" << std::endl;
is->play();
}
}
//Create a new ImageOverlay and set it's bounds,创建覆盖图并设置图的边界
//ImageOverlay* overlay = new ImageOverlay(mapNode->getMap()->getProfile()->getSRS()->getEllipsoid(), image);
ImageOverlay* overlay = new ImageOverlay(mapNode);
overlay->setImage( image.get() );
overlay->setBounds(imageBounds[i]);
// 覆盖图加入到mapNode
mapNode->addChild( overlay );
//Create a new ImageOverlayEditor and set it's node mask to 0 to hide it initially
// 遮盖图编辑器
osg::Node* editor = new ImageOverlayEditor( overlay, moveVert);
editor->setNodeMask( 1 );//编辑器的绿色点是否可见
mapNode->addChild( editor );
// Add an image preview 预览图
ImageControl* imageCon = new ImageControl( image.get() );
imageCon->setSize( 64, 64 );
imageCon->setVertAlign( Control::ALIGN_CENTER );
s_layerBox->setControl( 0, i, imageCon );
//Add some controls 复选框控件
CheckBoxControl* enabled = new CheckBoxControl( true );
enabled->addEventHandler( new EnabledHandler(overlay) );// checkbox控件的事件处理器,仅控制地图上的覆盖图显隐
enabled->setVertAlign( Control::ALIGN_CENTER );
s_layerBox->setControl( 1, i, enabled );
//The overlay name 获取到图片的名称
LabelControl* name = new LabelControl( osgDB::getSimpleFileName( imageFile) );
name->setVertAlign( Control::ALIGN_CENTER );
name->addEventHandler(new EnabledHandler(overlay));
//name->addEventHandler(new ChangeImageHandler(image, overlay, imageCon));// 同时控制地图上的覆盖图和预览图显隐
s_layerBox->setControl( 2, i, name );
// an opacity slider 滑块,更改透明度
HSliderControl* opacity = new HSliderControl( 0.0f, 1.0f, overlay->getAlpha() );// 设置范围
opacity->setWidth( 125 );
opacity->setHeight( 12 );
opacity->setVertAlign( Control::ALIGN_CENTER );
opacity->addEventHandler( new OpacityHandler(overlay) );// 添加事件处理器
s_layerBox->setControl( 3, i, opacity );
// Add a text label:
LabelControl* edit = new LabelControl( "Edit" );
edit->setVertAlign( Control::ALIGN_CENTER );
edit->addEventHandler(new EditHandler(overlay, &viewer, editor));
s_layerBox->setControl(4, i, edit );
// 替换遮盖图和预览图标。LabelControl不支持中文
LabelControl *change = new LabelControl("changeImage");
change->setVertAlign(Control::ALIGN_CENTER);
osg::ref_ptr image2 = osgDB::readRefImageFile("../data/fractal.png");// 替换一张图片
change->addEventHandler(new ChangeImageHandler(image2.get(), overlay, imageCon));
s_layerBox->setControl(5, i, change);
// 拖动图片编辑点,打印输出点的位置信息
LabelControl *position = new LabelControl("position");// 用于显示坐标信息
position->setVertAlign(Control::ALIGN_CENTER);
ImageOverlay::ControlPoint controlPoint(ImageOverlay::ControlPoint::CONTROLPOINT_CENTER);// 获取中心点的坐标
overlay->addCallback(new UpdateLabelCallback(position, overlay, controlPoint));// 为覆盖图添加回调方法
s_layerBox->setControl(6, i, position);
}
}
// add some stock OSG handlers:
viewer.addEventHandler(new osgViewer::StatsHandler());
viewer.addEventHandler(new osgViewer::WindowSizeHandler());
viewer.addEventHandler(new osgViewer::LODScaleHandler());
viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));
return viewer.run();
}