osgearth显⽰多维态势
⼀、代码
#include<Windows.h>
#include <osg/Notify>
#include <osgGA/StateSetManipulator>
#include <osgGA/GUIEventHandler>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgEarth/MapNode>
#include <osgEarth/XmlUtils>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/AutoClipPlaneHandler>
#include <osgEarthUtil/LinearLineOfSight>
#include <osgEarthUtil/RadialLineOfSight>
#include <osg/io_utils>
#include <osg/MatrixTransform>
#include <osg/Depth>
#include<osg/LineWidth>
#include<osg/ShapeDrawable>
#include<osgEarthAnnotation/PlaceNode>
using namespace osgEarth;
using namespace osgEarth::Util;
osg::AnimationPath* createAnimationPath(const GeoPoint& pos, const SpatialReference* mapSRS, float radius, double looptime) {
// set up the animation path
osg::AnimationPath* animationPath = new osg::AnimationPath;
animationPath->setLoopMode(osg::AnimationPath::LOOP);
int numSamples = 40;
double delta = osg::PI * 2.0 / (double)numSamples;
//Get the center point in geocentric
GeoPoint mapPos = ansform(mapSRS);
osg::Vec3d centerWorld;
bool isProjected = mapSRS->isProjected();
osg::Vec3d up = isProjected ? osg::Vec3d(0,0,1) : centerWorld;
//Get the "side" vector
osg::Vec3d side = isProjected ? osg::Vec3d(1,0,0) : up ^ osg::Vec3d(0,0,1);
double time=0.0f;
double time_delta = looptime/(double)numSamples;
osg::Vec3d firstPosition;
osg::Quat firstRotation;
for (unsigned int i = 0; i < (unsigned int)numSamples; i++)
{
double angle = delta * (double)i;
osg::Quat quat(angle, up );
osg::Vec3d spoke = quat * (side * radius);
osg::Vec3d end = centerWorld + spoke;
osg::Quat makeUp;
makeUp.makeRotate(osg::Vec3d(0,0,1), up);
osg::Quat rot = makeUp;
animationPath->insert(time,osg::AnimationPath::ControlPoint(end,rot));
if (i == 0)
{
firstPosition = end;
firstRotation = rot;
}
time += time_delta;
}
animationPath->insert(time, osg::AnimationPath::ControlPoint(firstPosition, firstRotation));
return animationPath;
}
osg::Node* createPlane(osg::Node* node, const GeoPoint& pos, const SpatialReference* mapSRS, double radius, double time) {
osg::MatrixTransform* positioner = new osg::MatrixTransform;
positioner->addChild( node );
osg::AnimationPath* animationPath = createAnimationPath(pos, mapSRS, radius, time);
positioner->setUpdateCallback( new osg::AnimationPathCallback(animationPath, 0.0, 1.0));
return positioner;
}
int main(int argc, char** argv)
{
osgViewer::Viewer viewer;
osg::ref_ptr<osg::Node>earthNode = osgDB::readNodeFile("clear_terrain.earth");
osg::Group* root = new osg::Group();
osgEarth::MapNode * mapNode = osgEarth::MapNode::findMapNode( earthNode );
if (!mapNode)
{
OE_NOTICE << "Could not find MapNode " << std::endl;
return 1;
}
osgEarth::Util::EarthManipulator* manip = new EarthManipulator();
viewer.setCameraManipulator( manip );
root->addChild( earthNode );
//Camera()->addCullCallback( new AutoClipPlaneCullCallback(mapNode));
osg::Group* losGroup = new osg::Group();
losGroup->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
losGroup->getOrCreateStateSet()->setAttributeAndModes(new osg::Depth(osg::Depth::ALWAYS, 0, 1, false));
root->addChild(losGroup);
// so we can speak lat/long:
//世界坐标和经纬坐标SRS
const SpatialReference* mapSRS = mapNode->getMapSRS();
const SpatialReference* geoSRS = mapSRS->getGeographicSRS();
//Create a point to point LineOfSightNode.
//第⼀根线
LinearLineOfSightNode* los = new LinearLineOfSightNode(
mapNode,
GeoPoint(geoSRS, -121.665, 46.0878, 1258.00, ALTMODE_ABSOLUTE),
GeoPoint(geoSRS, -121.488, 46.2054, 3620.11, ALTMODE_ABSOLUTE) );
osg::ref_ptr<osg::LineWidth>Lw2 = new osg::LineWidth(3);
los->getOrCreateStateSet()->setAttribute(Lw2, osg::StateAttribute::ON);
los->setGoodColor(osg::Vec4(0,0,1,1));
losGroup->addChild( los );
losGroup->addChild( los );
//Create an editor for the point to point line of sight that allows you to drag the beginning and end points around.
//This is just one way that you could manipulator the LineOfSightNode.
LinearLineOfSightEditor* p2peditor = new LinearLineOfSightEditor( los );
root->addChild( p2peditor );
//Create a relative point to point LineOfSightNode.
//第⼆根线两点之间⽣成⼀条线
LinearLineOfSightNode* relativeLOS = new LinearLineOfSightNode(
mapNode,
GeoPoint(geoSRS, -121.2, 46.1, 10, ALTMODE_RELATIVE),//最后⼀个参数相对⾼度为10 GeoPoint(geoSRS, -121.488, 46.2054, 10, ALTMODE_RELATIVE) );
osg::ref_ptr<osg::LineWidth>Lw3 = new osg::LineWidth(3);
relativeLOS->getOrCreateStateSet()->setAttribute(Lw3, osg::StateAttribute::ON);
relativeLOS->setGoodColor(osg::Vec4(0, 1, 1, 1));
未载入sso模块losGroup->addChild( relativeLOS );
//设置两条线为可编辑状态
LinearLineOfSightEditor* relEditor = new LinearLineOfSightEditor( relativeLOS );
root->addChild( relEditor );
//在⼭顶放⼀个坦克
osg::ref_ptr<osg::Node>tank = osgDB::readNodeFile("tank.flt.170,170,170.scale");
osg::MatrixTransform* tankMT = new osg::MatrixTransform;
osg::Matrix mt;
geoSRS->getEllipsoid()->computeLocalToWorldTransformFromLatLongHeight(osg::DegreesToRadians(46.2054), osg::DegreesToRadians(-121.488), 3430.11,m tankMT->setMatrix(mt);
tankMT->addChild(tank);
root->addChild(tankMT);
//Create a RadialLineOfSightNode that allows you to do a 360 degree line of sight analysis.
RadialLineOfSightNode* radial = new RadialLineOfSightNode( mapNode );
radial->setCenter( GeoPoint(geoSRS, -121.515, 46.054, 847.604, ALTMODE_ABSOLUTE) );
radial->setRadius( 2000 );
radial->setNumSpokes( 100 );
losGroup->addChild( radial );
//设置扇形可编辑
RadialLineOfSightEditor* radialEditor = new RadialLineOfSightEditor( radial );
losGroup->addChild( radialEditor );
//第⼆个扇形区域
//Create a relative RadialLineOfSightNode that allows you to do a 360 degree line of sight analysis.
RadialLineOfSightNode* radialRelative = new RadialLineOfSightNode( mapNode );
radialRelative->setCenter( GeoPoint(geoSRS, -121.2, 46.054, 10, ALTMODE_RELATIVE) );
radialRelative->setRadius( 3000 );
radialRelative->setNumSpokes(60);
losGroup->addChild( radialRelative );
//设置扇形可编辑
RadialLineOfSightEditor* radialRelEditor = new RadialLineOfSightEditor( radialRelative );
losGroup->addChild( radialRelEditor );
//Load a plane model.
osg::ref_ptr< osg::Node > plane = osgDB::readNodeFile("cessna.osgb.50,50,50.scale");//name.x,y,z.scale 猜测是点乘⽐例 name.x,ans 平移
//Create 2 moving planes
osg::Node* plane1 = createPlane(plane, GeoPoint(geoSRS, -121.656, 46.0935, 9133.06, ALTMODE_ABSOLUTE), mapSRS, 50000, 5); //半径时间
osg::Node* plane2 = createPlane(plane, GeoPoint(geoSRS, -121.321, 46.2587, 6390.09, ALTMODE_ABSOLUTE), mapSRS, 30000, 5);
root->addChild( plane1 );
root->addChild( plane2 );
//Create another plane and attach a RadialLineOfSightNode to it using the RadialLineOfSightTether
osg::Node* plane3 = createPlane(plane, GeoPoint(geoSRS, -121.463, 46.3548, 3348.71, ALTMODE_ABSOLUTE), mapSRS, 10000, 5);
osg::Node* plane3 = createPlane(plane, GeoPoint(geoSRS, -121.463, 46.3548, 3348.71, ALTMODE_ABSOLUTE), mapSRS, 10000, 5); plane3->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);
losGroup->addChild(plane3);
{
//Create a LineOfSightNode that will use a LineOfSightTether callback to monitor
//the two plane's positions and recompute the LOS when they move
//第⼀个和第⼆个飞机之间⽣成跟踪线
LinearLineOfSightNode* tetheredLOS = new LinearLineOfSightNode(mapNode);
超导失超
//设置跟踪线颜⾊
tetheredLOS->setGoodColor(osg::Vec4(0, 1, 0, 1));
//设置线宽
osg::ref_ptr<osg::LineWidth>Lw = new osg::LineWidth(3.0);
tetheredLOS->getOrCreateStateSet()->setAttribute(Lw, osg::StateAttribute::ON);
losGroup->addChild(tetheredLOS);
tetheredLOS->setUpdateCallback(new LineOfSightTether(plane1, plane2));
//第2和3架飞机之间的连接线
LinearLineOfSightNode* tetheredLOS2 = new LinearLineOfSightNode(mapNode);
//设置跟踪线颜⾊
tetheredLOS2->setGoodColor(osg::Vec4(1, 0, 0, 1)); //红⾊
//设置线宽
osg::ref_ptr<osg::LineWidth>Lw4 = new osg::LineWidth(3.0);
tetheredLOS2->getOrCreateStateSet()->setAttribute(Lw4, osg::StateAttribute::ON);
//不知道实际作⽤
//tetheredLOS2->setBadColor(osg::Vec4(1, 0, 0, 1));
losGroup->addChild(tetheredLOS2);
tetheredLOS2->setUpdateCallback(new LineOfSightTether(plane2, plane3));
//第1架飞机和坦克之间的连接线
LinearLineOfSightNode* tetheredLOS3 = new LinearLineOfSightNode(mapNode);
//设置跟踪线颜⾊
tetheredLOS3->setGoodColor(osg::Vec4(1, 0, 0, 1)); //红⾊
tetheredLOS3->getOrCreateStateSet()->setAttribute(Lw4, osg::StateAttribute::ON);
losGroup->addChild(tetheredLOS3);
tetheredLOS3->setUpdateCallback(new LineOfSightTether(plane1, tank));
}
{
RadialLineOfSightNode* tetheredRadia = new RadialLineOfSightNode(mapNode);
tetheredRadia->setRadius(5000);短期负荷预测
信息包
tetheredRadia->setFill(true);
//若只有GoodColor,则整个区域填充此颜⾊
tetheredRadia->setGoodColor(osg::Vec4(1, 0, 0, 0.3));
tetheredRadia->setNumSpokes(100);
losGroup->addChild(tetheredRadia);
tetheredRadia->setUpdateCallback(new RadialLineOfSightTether(tank));
//飞机1周围的包围扇形
RadialLineOfSightNode* tetheredRadia2 = new RadialLineOfSightNode(mapNode);
tetheredRadia2->setRadius(5000);
tetheredRadia2->setFill(true);
//若只有GoodColor,则整个区域填充此颜⾊
tetheredRadia2->setGoodColor(osg::Vec4(0, 1, 0, 0.3));
tetheredRadia2->setNumSpokes(100);
losGroup->addChild(tetheredRadia2);
tetheredRadia2->setUpdateCallback(new RadialLineOfSightTether(plane1));
//飞机2周围的包围扇形
RadialLineOfSightNode* tetheredRadia3 = new RadialLineOfSightNode(mapNode);
RadialLineOfSightNode* tetheredRadia3 = new RadialLineOfSightNode(mapNode);
tetheredRadia3->setRadius(5000);
tetheredRadia3->setFill(true);
//若只有GoodColor,则整个区域填充此颜⾊
tetheredRadia3->setGoodColor(osg::Vec4(0, 1, 0, 0.3));
tetheredRadia3->setNumSpokes(100);
losGroup->addChild(tetheredRadia3);
tetheredRadia3->setUpdateCallback(new RadialLineOfSightTether(plane2));
//飞机3周围的包围扇形
RadialLineOfSightNode* tetheredRadia4 = new RadialLineOfSightNode(mapNode);
tetheredRadia4->setRadius(5000);
//This RadialLineOfSightNode is going to be filled, so set some alpha values for the colors so it's partially transparent
tetheredRadia4->setFill(true);
//若只有GoodColor,则整个区域填充此颜⾊
tetheredRadia4->setGoodColor(osg::Vec4(1, 0, 0, 0.3));
//BadColor好像没啥影响
//后⾯参数为多边形外接切线,参数越⼤越接近圆,参数越⼩则退化为正多边形
包装内托
tetheredRadia4->setNumSpokes(100);
losGroup->addChild(tetheredRadia4);
//设置包围圈跟踪飞机模型
tetheredRadia4->setUpdateCallback(new RadialLineOfSightTether(plane3));
//包围球
osg::ref_ptr<osg::Geode> gnode = new osg::Geode;
osg::BoundingSphere bs = plane3->getBound();
osg::ref_ptr<osg::ShapeDrawable> sd = new osg::ShapeDrawable(new osg::(),bs.radius()+300));
sd->setColor(osg::Vec4(1,0,0,0.2));
gnode->addChild(sd);
osg::MatrixTransform* plane3MT = dynamic_cast<osg::MatrixTransform*>(plane3);
plane3MT->addChild(gnode);
gnode->getOrCreateStateSet()->setMode(GL_BLEND,osg::StateAttribute::ON|osg::StateSet::TRANSPARENT_BIN);
gnode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
//添加标识
osgEarth::Style style;
osgEarth::Annotation::PlaceNode *pn = new osgEarth::Annotation::PlaceNode(mapNode, osgEarth::GeoPoint(geoSRS, -121.488, 46.2054, 0, ALTMODE_RELAT root->addChild(pn);
}
//设置初始视点
osgEarth::Viewpoint vp;
vp.name() = "Mt Ranier";
vp.focalPoint()->set(geoSRS, -121.488, 46.2054, 0, ALTMODE_ABSOLUTE);
卡口摄像头
vp.pitch() = -50.0;
vp.range() = 100000;
manip->setHomeViewpoint( vp );
viewer.setSceneData( root );
// add some stock OSG handlers:
viewer.addEventHandler(new osgViewer::StatsHandler());
viewer.addEventHandler(new osgViewer::WindowSizeHandler());
viewer.addEventHandler(new osgViewer::ThreadingHandler());
viewer.addEventHandler(new osgViewer::LODScaleHandler());
viewer.addEventHandler(new osgGA::Camera()->getOrCreateStateSet()));
return viewer.run();
}