部分关键代码:
//三维航迹
class Track3D:public Pendant {
public:
Track3D();
~Track3D();
//在OsgEarth上创建线
void createTrackOnEarth(std::vector<TrackPoint*>&pts);
//创建线作为Osg的节点
void createTrackOnNode(std::vector<TrackPoint*>&pts);
void clearSelf()override;
private:
osgEarth::Annotation::FeatureNode* _pathNode = nullptr;//在earth表面上的线
osg::ref_ptr<osg::MatrixTransform> _nodeMtTrack;//作为节点的线模型
};
#include "Track3D.h"
#include "Track/Track.h"
#include "Track/TrackPoint.h"
#include "EarthMapManager.h"
#include <osg/LineWidth>
Track3D::Track3D():Pendant(PST3D_TRACK) {
}
Track3D::~Track3D() {
}
void Track3D::createTrackOnEarth(std::vector<TrackPoint*>&pts) {
if (pts.empty()) {
return ;
}
int num = pts.size();
if (num == 0) {
return ;
}
osgEarth::Symbology::Geometry* path = new osgEarth::Symbology::LineString();
for (int i = 0; i < num; i++) {
TrackPoint* one = pts.at(i);
path->push_back(osg::Vec3d(one->getLon(), one->getLat(), one->getAlt()));
}
osgEarth::Features::Feature* pathFeature = new osgEarth::Features::Feature(path, EarthMapMgr()->getMapNode()->getMapSRS());
pathFeature->geoInterp() = osgEarth::GEOINTERP_RHUMB_LINE;
osgEarth::Symbology::Style pathStyle;
pathStyle.getOrCreate<osgEarth::Symbology::LineSymbol>()->stroke()->color() = osgEarth::Symbology::Color(osg::Vec4f(1.0, 0.0, 0.0, 1.0));
pathStyle.getOrCreate<osgEarth::Symbology::LineSymbol>()->stroke()->width() = 2.0;
#if 0
pathStyle.getOrCreate<osgEarth::Symbology::LineSymbol>()->stroke()->widthUnits() = osgEarth::Units::PIXELS;
#else
pathStyle.getOrCreate<osgEarth::Symbology::LineSymbol>()->stroke()->widthUnits() = osgEarth::Units::KILOMETERS;
#endif
#if 1
pathStyle.getOrCreate<osgEarth::Symbology::LineSymbol>()->stroke()->stipple() = 0xFFF0;
#else
pathStyle.getOrCreate<osgEarth::Symbology::LineSymbol>()->stroke()->stipple() = 0xFFFF;
#endif
pathStyle.getOrCreate<osgEarth::Symbology::LineSymbol>()->tessellationSize() = 75000;
#if 1//是否显示航迹点
pathStyle.getOrCreate<osgEarth::Symbology::PointSymbol>()->size() = 3.0;
pathStyle.getOrCreate<osgEarth::Symbology::PointSymbol>()->fill()->color() = osgEarth::Symbology::Color(osg::Vec4f(0.0, 0.0, 0.5, 0.5));
#endif
#if 1//真实的等高线
pathStyle.getOrCreate<osgEarth::Symbology::AltitudeSymbol>()->clamping() = osgEarth::Symbology::AltitudeSymbol::CLAMP_NONE;//CLAMP_TO_TERRAIN
pathStyle.getOrCreate<osgEarth::Symbology::AltitudeSymbol>()->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_SCENE;//TECHNIQUE_DRAPE
#else//贴地皮绘制线
pathStyle.getOrCreate<osgEarth::Symbology::AltitudeSymbol>()->clamping() = osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN;
pathStyle.getOrCreate<osgEarth::Symbology::AltitudeSymbol>()->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE;
#endif
pathStyle.getOrCreate<osgEarth::Symbology::RenderSymbol>()->depthOffset()->enabled() = true;
pathStyle.getOrCreate<osgEarth::Symbology::AltitudeSymbol>()->verticalOffset() = 1.0;
_pathNode = new osgEarth::Annotation::FeatureNode(pathFeature, pathStyle);
EarthMapMgr()->getMapNode()->addChild(_pathNode);
}
void Track3D::createTrackOnNode(std::vector<TrackPoint*>&pts) {
if (pts.empty()) {
return ;
}
int num = pts.size();
if (num == 0) {
return ;
}
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
osg::ref_ptr<osg::Vec3Array> pointVector = new osg::Vec3Array;
osg::ref_ptr<osg::Vec4Array> colorArray = new osg::Vec4Array;
osg::ref_ptr<osg::Vec3Array> normalArray = new osg::Vec3Array;
std::vector<osg::Matrix> matrixVector;
osg::Matrix axisRotate = osg::Matrix::rotate(osg::Vec3(0, 0, 1), osg::Vec3(0, 0, 1));
for (int i = 0; i < pts.size(); i++) {
osg::Matrix m;
EarthMapMgr()->getMapNode()->getMapSRS()->getEllipsoid()
->computeLocalToWorldTransformFromLatLongHeight(osg::DegreesToRadians(pts[i]->getLat()),
osg::DegreesToRadians(pts[i]->getLon()),
pts[i]->getAlt(),
m);
if (true) {
if (i != pts.size() - 1) {
osg::Vec3 p1(pts[i]->getLon(), pts[i]->getLat(), 0);
osg::Vec3 p2(pts[i + 1]->getLon(), pts[i + 1]->getLat(), 0);
osg::Vec3 dp = p2 - p1;
if (dp.length() > 10e-3) {
dp.normalize();
m = osg::Matrix::rotate(osg::Vec3(0, 1, 0), dp) * m * axisRotate;
}
} else {//轨迹的最后一个点,需要特殊处理
osg::Vec3 p1(pts[i - 1]->getLon(), pts[i - 1]->getLat(), 0);
osg::Vec3 p2(pts[i]->getLon(), pts[i]->getLat(), 0);
osg::Vec3 dp = p2 - p1;
if (dp.length() > 10e-3) {
dp.normalize();
m = osg::Matrix::rotate(osg::Vec3(0, 1, 0), dp) * m* axisRotate;
}
}
}
pointVector->push_back(m.getTrans());
matrixVector.push_back(m);
}
geom->setVertexArray(pointVector.get());
geom->setColorArray(colorArray.get());
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
geom->setNormalArray(normalArray.get());
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
normalArray->push_back(osg::Vec3(0.f, 0.f, 1.f));
//set data
colorArray->push_back(osg::Vec4(1.0, 0.0, 0.0, 1));
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, pointVector->size()));
//line-size
osg::LineWidth* lineWidth = new osg::LineWidth;
lineWidth->setWidth(2);
geom->getOrCreateStateSet()->setAttributeAndModes(lineWidth, osg::StateAttribute::ON);
osg::ref_ptr<osg::Geode> m_geode = new osg::Geode;
m_geode->addDrawable(geom);
osg::StateSet* stateset = m_geode->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
_nodeMtTrack = new osg::MatrixTransform;
_nodeMtTrack->addChild(m_geode);
EarthMapMgr()->getModelRoot()->addChild(_nodeMtTrack);
_nodeMtTrack->addDescription("trajectory");
}
void Track3D::clearSelf() {
if (_pathNode != nullptr){
EarthMapMgr()->getMapNode()->removeChild(_pathNode);
}
if (_nodeMtTrack != nullptr){
EarthMapMgr()->getModelRoot()->removeChild(_nodeMtTrack);
}
}
aaa