|
楼主 |
发表于 2015-1-16 18:13:47
|
显示全部楼层
本帖最后由 anlingbin 于 2015-1-16 18:24 编辑
代码大概是这样:
#include <osgGA/GUIEventHandler>
#include <osgUtil/LineSegmentIntersector>
#include <osgUtil/PolytopeIntersector>
#include <osgViewer/View>
#include <osgEarth/Pickers>
#include <osgEarth/MapNode>
#include <osgEarthAnnotation/FeatureNode>
class PolygonNodeHandler : public osgGA::GUIEventHandler
{
public:
PolygonNodeHandler(void) {}
virtual ~PolygonNodeHandler(void) {}
// 事件处理
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
if (ea.getHandled()) {
return false;
}
if (!_view.valid()) {
_view = dynamic_cast<osgViewer::View*>(&aa);
_mapNode = osgEarth::MapNode::findMapNode(_view->getSceneData());
}
bool handled = false;
switch (ea.getEventType())
{
case osgGA::GUIEventAdapter:USH:
if (ea.getButtonMask() == osgGA::GUIEventAdapter:EFT_MOUSE_BUTTON)
{
xMouse = ea.getX();
yMouse = ea.getY();
}
break;
case osgGA::GUIEventAdapter::RELEASE:
{
if (xMouse == ea.getX() && yMouse == ea.getY())
{
osg::Vec3d world;
if (_mapNode->getTerrain()->getWorldCoordsUnderMouse(_view.get(), xMouse, yMouse, world)) {
osgEarth::GeoPoint coordinate;
coordinate.fromWorld(_mapNode->getMapSRS(), world);
addPosition(coordinate);
return true;
}
}
}
break;
case osgGA::GUIEventAdapter::MOVE:
{
osg::Vec3d world;
if (_mapNode->getTerrain()->getWorldCoordsUnderMouse(_view.get(), ea.getX(), ea.getY(), world)) {
osgEarth::GeoPoint coordinate;
coordinate.fromWorld(_mapNode->getMapSRS(), world);
setPosition(coordinate);
return true;
}
}
break;
}
return handled;
}
void addPosition(const osgEarth::GeoPoint& pos)
{
if (!_polygon.valid()) {
_polygon = new osgEarth::Symbology::Polygon();
_polygon->push_back(pos.vec3d());
_polygon->push_back(pos.vec3d()); // 以两点相同的面模拟一条线段
}
_polygon->push_back(pos.vec3d());
if (_polygonNode.valid()) {
_polygonNode->init();
} else {
osgEarth::Symbology::Style style;
style.getOrCreate<LineSymbol>()->stroke()->color() = Color(Color::Green, 1.0);
style.getOrCreate<LineSymbol>()->stroke()->width() = 2.0;
style.getOrCreate<olygonSymbol>()->fill()->color() = Color(Color::Yellow, 0.5);
style.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_NONE;
//style.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU;
_polygonFeature = new osgEarth::Features::Feature(_polygon.get(), _mapNode->getMapSRS(), style);
_polygonNode = new osgEarth::Annotation::FeatureNode(_mapNode.get(), _polygonFeature.get(), true);
_polygonNode->getOrCreateStateSet()->setRenderBinDetails(11, "RenderBin");
_polygonNode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
_polygonNode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
//_polygonNode->setDynamic(true);
osg::Group* root = dynamic_cast<osg::Group*>(_view->getSceneData());
root->addChild(_polygonNode.get());
}
}
void setPosition(const osgEarth::GeoPoint& pos)
{
if (_polygon.valid() && _polygon->size() > 1) {
_polygon->back() = pos.vec3d();
if (_polygonNode.valid()) {
// 如果多边形的点距离太远,例如相聚经度180度,可能由于计算量太大,导致渲染停滞,但主要发生在跨越180度时,是否代码问题
// 解决方法1、先将节点从其父节点删除,然后另起线程计算,完成后再把该节点添加到其原父节点
// 解决方法2、是否可以修改计算代码,加快速度?
// 当前采用方法1
_polygonNode->init();
}
}
}
protected:
float xMouse;
float yMouse;
osg::ref_ptr<osgEarth::Symbology::Polygon> _polygon;
osg::ref_ptr<osgEarth::Features::Feature> _polygonFeature;
osg::ref_ptr<osgEarth::Annotation::FeatureNode> _polygonNode;
osg:bserver_ptr<osgEarth::MapNode> _mapNode;
osg::observer_ptr<osgViewer::View> _view;
};
|
|