#include "StdAfx.h"
#include "OsgPieChart.h"
#include "OsgEarthEngine.h"
#include <cstdio>
#include <iostream>
#include <osgEarth/Utils>
#include <osgEarth/Registry>
#include <osgEarth/ShaderGenerator>
#include <osg/Depth>
#include <osg/MatrixTransform>
#include <osg/Matrixd>
#include <osg/AnimationPath>
#include <osgEarthAnnotation/AnnotationUtils>
#include <osgEarthAnnotation/AnnotationRegistry>
using namespace std;
OsgPieChart::OsgPieChart( OsgEarthEngine* pOsgEngine, const osg::Vec3 xyz,double RVarlue/*=5*/,double GVarlue/*=5*/,double BVarlue/*=10*/,double FVarlue/*=10*/ )
:m_pOsgEngine(pOsgEngine)
{
m_Height =2000;
m_LBH=osg::Vec3(xyz.x(),xyz.y(),m_Height);
m_Pieradius = 1;
m_PieValue = new double[4];
m_PieValue[0] = RVarlue;
m_PieValue[1] = GVarlue;
m_PieValue[2] = BVarlue;
m_PieValue[3] = FVarlue;
m_Mat = NULL;
m_preScale = 1;
m_PtCallback = new OsgChartCallBack(this);
m_ptUpdataCallback=new OsgChartUpdataCallBack(this);
setEventCallback(m_PtCallback);
setUpdateCallback(m_ptUpdataCallback);
CreatePieChart(m_Pieradius,m_PieValue);
}
OsgPieChart::~OsgPieChart(void)
{
}
void OsgPieChart::CreatePieChart( double PieRadius,double* PieValue )
{
if (!PieValue)
return;
void* pMap = NULL;
void* pRoot = NULL;
void* pViewer = NULL;
m_pOsgEngine->GetRawPointer(&pMap,&pRoot,&pViewer);
osgEarth::Map* map = (osgEarth::Map*)pMap;
osg::Group* earthRoot = (osg::Group*)pRoot;
osgEarth::MapNode* mapNode = osgEarth::findTopMostNodeOfType<osgEarth::MapNode>(earthRoot);
const osgEarth::SpatialReference* pSRS = map->getProfile()->getSRS();
osg::ref_ptr<osg::MatrixTransform> pMt = new osg::MatrixTransform;
osg::Matrixd matrix;
osgEarth::GeoPoint geoPoint(pSRS, m_LBH, osgEarth::ALTMODE_ABSOLUTE);
geoPoint.createLocalToWorld( matrix );
pMt->setMatrix(matrix);
std::string pre;
double startA=0;
double endA=0;
m_Mat = pMt;
GetPrecent(OSGPIECHART_R,pre,startA,endA);
osg::ref_ptr<osg::Geode> nodedraw1 = DrawSector(OSGPIECHART_R,osg::Vec3(0,0,0),PieRadius, 1000,startA,endA,0.0,osgEarth::Annotation::Color("#446EA1FF"),pre);
nodedraw1->setName("Pie_1");
pMt->addChild(nodedraw1);
GetPrecent(OSGPIECHART_G,pre,startA,endA);
osg::ref_ptr<osg::Geode> nodedraw2 = DrawSector(OSGPIECHART_G,osg::Vec3(0,0,0),PieRadius, 1000,startA,endA,0.0,osgEarth::Annotation::Color("#C0504DFF"),pre);
nodedraw2->setName("Pie_2");
pMt->addChild(nodedraw2);
GetPrecent(OSGPIECHART_B,pre,startA,endA);
osg::ref_ptr<osg::Geode> nodedraw3 = DrawSector(OSGPIECHART_B,osg::Vec3(0,0,0),PieRadius, 1000,startA,endA,0.0,osgEarth::Annotation::Color("#A4C168ff"),pre);
nodedraw3->setName("Pie_3");
pMt->addChild(nodedraw3);
GetPrecent(OSGPIECHART_F,pre,startA,endA);
osg::ref_ptr<osg::Geode> nodedraw4 = DrawSector(OSGPIECHART_F,osg::Vec3(0,0,0),PieRadius, 1000,startA,endA,0.0,osgEarth::Annotation::Color("#624C7Cff"),pre);
nodedraw4->setName("Pie_4");
pMt->addChild(nodedraw4);
pMt->setName(this->getName());
pMt->addChild(createLights(osg::Vec3(0,0,0),nodedraw1->getOrCreateStateSet()));
pMt->addChild(createLights(osg::Vec3(0,0,0),nodedraw2->getOrCreateStateSet()));
pMt->addChild(createLights(osg::Vec3(0,0,0),nodedraw3->getOrCreateStateSet()));
pMt->addChild(createLights(osg::Vec3(0,0,0),nodedraw4->getOrCreateStateSet()));
addChild(pMt,true);
// ShowPieText( OSGPIECHART_R,false );
// ShowPieText( OSGPIECHART_G,false );
// ShowPieText( OSGPIECHART_B,false );
// ShowPieText( OSGPIECHART_F,false );
}
bool OsgPieChart::AdpatRadioAndHeight( double& radio,double* height )
{
double dDis;
double dScale;
double x, y, z, B, L, H, dAz, dEl;
DOUBLEPOINT3D point3D;
m_pOsgEngine->m_pGlobalEllipse->T_BLHToXYZ(m_LBH.x(), m_LBH.y(), m_LBH.z(),point3D.x,point3D.y,point3D.z);
m_pOsgEngine->GetEyePostion(x,y,z,B,L,H,dAz,dEl);
dDis = DistanceBetweenTwoPoints(x,y,z,point3D.x,point3D.y,point3D.z);
dScale = dDis/1000;
if(dScale<50)
dScale = 50;
if(dScale>15000.)
dScale = 15000.;
if(fabs(m_preScale-dScale)<10)
return false;
radio = 2*dScale;
m_preScale=dScale;
return true;
}
osg::ref_ptr<osgText::Text> OsgPieChart::CreateText( std::string strText,osg::Vec3& vecPos,osg::Vec4 color/*=osg::Vec4(0.0,0.0,0.0,1.0)*/,float size/*=20*/,std::string strFont/*=std::string("E:\\U3dcode\\simsunb.ttf")*/,osgText::Text::AlignmentType nAlign/*=osgText::Text::CENTER_BOTTOM*/ )
{
setlocale(LC_ALL,".936");//设定环境
const char* bz2=strText.c_str();
int nSize=mbstowcs(NULL,bz2,0);//字符转换
wchar_t*wbz2=new wchar_t[nSize+1];
mbstowcs(wbz2,bz2,(nSize+1));
osgText::String wText2(wbz2);
osg::ref_ptr<osgText::Text> text=new osgText::Text;
text->setText(wText2);
//delete wbz2;
osg::ref_ptr<osgText::Font>font=new osgText::Font();
font=osgText::readFontFile(strFont);
text->setFont(font.get());
if(size>0)
text->setCharacterSize(2000); //设定大小
else if(size==0)
text->setCharacterSizeMode(osgText::TextBase::SCREEN_COORDS); //根据屏幕坐标自动缩放
else
text->setCharacterSizeMode(osgText::TextBase::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT);//根据视点自动缩放
text->setColor(color);
text->setPosition(vecPos);
text->setAlignment(nAlign);
text->setAxisAlignment(osgText::Text::SCREEN);
return text.release();
}
osg::ref_ptr<osg::Geode> OsgPieChart::DrawSector( int PieType,osg::Vec3 vecCenter, float radius, float height, float startAngle, float endAngle, float delta,osgEarth::Annotation::Color vecColor,std::string strText/*=std::string("")*/ )
{
osg::ref_ptr<osg::Geode> geode=new osg::Geode;//扇体节点
osg::Quat qu;//扇体外移
qu.makeRotate((startAngle+endAngle)/2.0,osg::Vec3(0,0,1));
osg::Matrix ma;
ma.makeRotate(qu);
vecCenter+=osg::Vec3(1,0,0)*delta*ma;
if (!strText.empty())
{
//osg::Vec3 vecText=vecCenter+osg::Vec3(1,0,0)*radius*ma*0.6+osg::Vec3(0,0,height*1.2);
geode->addDrawable(osg::createTexturedQuadGeometry(osg::Vec3(-15.0, 1.0, -13.0),osg::Vec3(30.0,0.0,0.0),osg::Vec3(0.0,0.0,20.0),1.0,1.0));//创建一个写字板
addChild(getOrCreateText(PieType,ChangeLBH(radius,startAngle,endAngle),strText,vecColor),false);
}
osg::ref_ptr<osg::Vec3Array> v3Qu=new osg::Vec3Array;//记录侧边顶点
osg::ref_ptr<osg::Vec3Array>v3Tr=new osg::Vec3Array;//扇形顶点
v3Qu->push_back(vecCenter);
v3Qu->push_back(vecCenter+osg::Vec3(0,0,height));
v3Tr->push_back(vecCenter+osg::Vec3(0,0,height));
float curAngle=startAngle;
while(1)
{
osg::Vec3 down=vecCenter+osg::Vec3(radius*cos(curAngle),radius*sin(curAngle),0);
osg::Vec3 top=down+osg::Vec3(0,0,height);
v3Qu->push_back(down);
v3Qu->push_back(top);
v3Tr->push_back(top);
if (endAngle>curAngle)
{
if(endAngle>curAngle+0.03)//小扇形顶角为.03弧度
curAngle+=0.03;
else
curAngle=endAngle;
}
else
break;
}
v3Qu->push_back(vecCenter);
v3Qu->push_back(vecCenter+osg::Vec3(0,0,height));
osg::ref_ptr<osg::Vec4Array>v4Qu=new osg::Vec4Array;
v4Qu->push_back(vecColor);
osg::ref_ptr<osg::Geometry> geomQu=new osg::Geometry;
geomQu->setVertexArray(v3Qu.get());
geomQu->setColorArray(v4Qu.get());
geomQu->setColorBinding(osg::Geometry::BIND_OVERALL);
geomQu->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,v3Qu->size()));
osg::ref_ptr<osg::Vec4Array>v4Tri=new osg::Vec4Array;
v4Tri->push_back(vecColor);
osg::ref_ptr<osg::Geometry>geomTri=new osg::Geometry;
geomTri->setVertexArray(v3Tr.get());
geomTri->setColorArray(v4Tri.get());
geomTri->setColorBinding(osg::Geometry::BIND_OVERALL);
geomTri->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN,0,v3Tr->size()));
osg::StateSet* stateset =new osg::StateSet; //透明属性设置
stateset->setMode(GL_BLEND,osg::StateAttribute::OFF); //Alpha混合开启
stateset->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON ); //取消深度测试
stateset->setMode( GL_LIGHTING, osg::StateAttribute::ON );
//stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
stateset->setRenderBinDetails(1, "RenderBin");
geomQu->setStateSet(stateset);
geomTri->setStateSet(stateset);
osg::ref_ptr<osg::Material> material=new osg::Material;
material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4f(100.0,100.0,100.0,1.0));
material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4f(1.0,1.0,1.0,1.0));
material->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4f(1.0,1.0,1.0,1.0));
geode->getOrCreateStateSet()->setAttribute(material,osg::StateAttribute::ON);
geode->addDrawable(geomQu.get());
geode->addDrawable(geomTri.get());
geode->addDescription(std::string("sector"));
return geode.release();
}
void OsgPieChart::UpdataChart()
{
if(!AdpatRadioAndHeight(m_Pieradius, m_PieValue))
return;
if (m_Mat)
{
this->removeChild(m_Mat);
m_Mat = NULL;
}
CreatePieChart(m_Pieradius,m_PieValue);
}
void OsgPieChart::GetPrecent( int PieType, std::string& Pre,double& startAngle,double& endAngle )
{
double sum= m_PieValue[0]+ m_PieValue[1]+ m_PieValue[2]+m_PieValue[3];
double preR=m_PieValue[0]/sum;
double preG=m_PieValue[1]/sum;
double preB=m_PieValue[2]/sum;
double preF=m_PieValue[3]/sum;
char buffer[20];
switch(PieType)
{
case OSGPIECHART_R :
Pre=GetStringPre(preR);
startAngle = 0;
endAngle = osg::DegreesToRadians(preR*360);
break;
case OSGPIECHART_G :
Pre=GetStringPre(preG);
startAngle = osg::DegreesToRadians(preR*360);
endAngle = osg::DegreesToRadians(((m_PieValue[0]+ m_PieValue[1])/sum)*360);
break;
case OSGPIECHART_B :
Pre=GetStringPre(preB);
startAngle = osg::DegreesToRadians(((m_PieValue[0]+ m_PieValue[1])/sum)*360);
endAngle = osg::DegreesToRadians(((m_PieValue[0]+ m_PieValue[1]+m_PieValue[2])/sum)*360);
break;
case OSGPIECHART_F :
Pre=GetStringPre(preF);
startAngle = osg::DegreesToRadians(((m_PieValue[0]+ m_PieValue[1]+m_PieValue[2])/sum)*360);
endAngle = osg::DegreesToRadians(360.0);
break;
default:
break;
}
}
std::string OsgPieChart::GetStringPre( double PreNum )
{
PreNum*=100;
char buffer[20];
std::string strtemp;
sprintf_s(buffer,"%.2f",PreNum);
strtemp=std::string(buffer)+"%";
return strtemp;
}
void OsgPieChart::Pick( float x,float y )
{
void* pMap = NULL;
void* pRoot = NULL;
void* pViewer = NULL;
m_pOsgEngine->GetRawPointer(&pMap,&pRoot,&pViewer);
osgViewer::Viewer* view = (osgViewer::Viewer*)pViewer;
osgUtil::LineSegmentIntersector::Intersections intersections;
if (view->computeIntersections(x,y,intersections))
{
for ( osgUtil::LineSegmentIntersector::Intersections::iterator hitr= intersections.begin();hitr != intersections.end();++hitr)
{
if (!hitr->nodePath.empty())
{
const osg::NodePath& np = hitr->nodePath;
for (int i = np.size()-1;i>=0;--i)
{
osg::ref_ptr<osg::Geode> node = dynamic_cast<osg::Geode*>(np[i]);
if (node)
{
if (!(node->getName().empty()) && strcmp(node->getName().c_str(),m_preSeleced.c_str())!=0 )
{
std::string _name = node->getName();
if (_name=="Pie_1" && strcmp(m_Mat->getName().c_str(),node->getParent(0)->getName().c_str())==0)
{
ShowPieText(OSGPIECHART_R);
m_preSeleced=_name;
}
else if(_name=="Pie_2" && strcmp(m_Mat->getName().c_str(),node->getParent(0)->getName().c_str())==0)
{
ShowPieText(OSGPIECHART_G);
m_preSeleced=_name;
}
else if(_name=="Pie_3" && strcmp(m_Mat->getName().c_str(),node->getParent(0)->getName().c_str())==0)
{
ShowPieText(OSGPIECHART_B);
m_preSeleced=_name;
}
else if(_name=="Pie_4" && strcmp(m_Mat->getName().c_str(),node->getParent(0)->getName().c_str())==0)
{
ShowPieText(OSGPIECHART_F);
m_preSeleced=_name;
}
else
{
ShowPieText(OSGPIECHART_F,false);
ShowPieText(OSGPIECHART_G,false);
ShowPieText(OSGPIECHART_B,false);
ShowPieText(OSGPIECHART_F,false);
}
}
}
}
}
}
}
else
{
ShowPieText(OSGPIECHART_F,false);
ShowPieText(OSGPIECHART_G,false);
ShowPieText(OSGPIECHART_B,false);
ShowPieText(OSGPIECHART_F,false);
}
}
osg::Vec3 OsgPieChart::ChangeLBH(float radius,float startAngle, float endAngle)
{
osg::Vec3 vectem;
double mulangle=(startAngle+endAngle)/2.0;
double offsetx,offsety;
offsetx =cos(mulangle)*(radius*0.6/100000);
offsety =sin(mulangle)*(radius*0.6/100000);
vectem.set(m_LBH.x()+offsetx,m_LBH.y()+offsety,m_Height+1200);
return vectem;
}
osg::ref_ptr<osg::MatrixTransform> OsgPieChart::getOrCreateText( int PieType ,osg::Vec3& vecPos,std::string strText,osgEarth::Annotation::Color vecColor )
{
map<int,osg::ref_ptr<osg::MatrixTransform>>::iterator iter = m_TextVec.find(PieType);
char ch[50];
itoa(PieType,ch,10);
std::string strName = "OrthonodeText_"+std::string(ch);
if(iter != m_TextVec.end())
{
int nCount = this->getNumChildren();
for(int i=0;i<nCount;++i)
{
if(strcmp((this->getChild(i)->getName()).c_str(),strName.c_str())==0)
{
this->removeChild(this->getChild(i));
break;
}
}
m_TextVec.erase(iter);
}
osg::ref_ptr<osg::MatrixTransform> mat = new osg::MatrixTransform(osg::Matrixd::translate(osg::Vec3(0,0,0)));
osg::ref_ptr<OrthoNode> Orthonode = CreateTextQQ(strText,vecPos,vecColor);
mat->addChild(Orthonode);
mat->setName(strName);
m_TextVec.insert(pair<int,osg::ref_ptr<osg::MatrixTransform>>(PieType,mat));
//ShowPieText(PieType,false);
return m_TextVec[PieType];
}
osg::ref_ptr<OrthoNode> OsgPieChart::CreateTextQQ( std::string strText,osg::Vec3& vecPos,osgEarth::Annotation::Color color,int RGB/*=0*/ )
{
void* pMap = NULL;
void* pRoot = NULL;
void* pViewer = NULL;
m_pOsgEngine->GetRawPointer(&pMap,&pRoot,&pViewer);
osgEarth::Map* map = (osgEarth::Map*)pMap;
osg::Group* earthRoot = (osg::Group*)pRoot;
osgEarth::MapNode* mapNode = osgEarth::findTopMostNodeOfType<osgEarth::MapNode>(earthRoot);
osgEarth::GeoPoint geoPoint(map->getProfile()->getSRS(),vecPos, osgEarth::ALTMODE_ABSOLUTE);
osg::ref_ptr<OrthoNode> pOrthonode = new OrthoNode(mapNode,geoPoint);
ShaderGenerator gen;
osg::ref_ptr<osg::Geode> geodeT = new osg::Geode;
osg::ref_ptr<osg::Drawable> text1 = 0L;
double textlen = (strText.size()/2)*10;
osg::ref_ptr<osg::MatrixTransform> mat = new osg::MatrixTransform(osg::Matrix(osg::Matrixd::translate(osg::Vec3(-textlen,0,0))));
osg::ref_ptr<osg::StateSet> stateSet = geodeT->getOrCreateStateSet();
osg::ref_ptr<AnnotationData> ad = pOrthonode->getAnnotationData();
TextSymbol textsymbol1;
textsymbol1.size() = 20;
textsymbol1.font() = Str(m_pOsgEngine->m_strDataFilesPath+"\\fonts\\arial.ttf");
textsymbol1.encoding() = osgEarth::Symbology::TextSymbol::ENCODING_UTF8;
textsymbol1.declutter() = true;
textsymbol1.fill()->color() = color;
textsymbol1.halo()->color() = osg::Vec4(1.0,1.0,1.0,1.0);
std::string strl;
gb2312ToUtf8(strText,strl);
text1 = AnnotationUtils::createTextDrawable(strl,&textsymbol1,osg::Vec3(0,0,0));
if ( text1 )
{
text1->setName("text1");
geodeT->addDrawable(text1);
mat->addChild(geodeT);
pOrthonode->getAttachPoint()->addChild(mat);
}
stateSet->setMode(GL_BLEND,osg::StateAttribute::OFF); //Alpha混合开启
stateSet->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON ); //取消深度测试
stateSet->setMode( GL_LIGHTING, osg::StateAttribute::ON );
//stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
stateSet->setRenderBinDetails(11, "RenderBin");
stateSet->setAttributeAndModes( new osg::Depth(osg::Depth::ALWAYS, 0, 1, false), 1 );
gen.setProgramName( "OsgCylinder" );
gen.run( pOrthonode, Registry::stateSetCache() );
if (ad)
pOrthonode->setAnnotationData(ad);
return pOrthonode;
}
vector<double> OsgPieChart::ShowPieText( int PieType,bool isShow )
{
bool isFind =false;
vector<double> reText;
map<int,osg::ref_ptr<osg::MatrixTransform>>::iterator iter = m_TextVec.find(PieType);
if(iter != m_TextVec.end())
isFind = true ;
map<int,osg::ref_ptr<osg::MatrixTransform>>::iterator itertemp = m_TextVec.begin();
for(;itertemp!=m_TextVec.end();++itertemp)
{
if(iter == itertemp && isFind)
this->setChildValue((itertemp->second),isShow);
else
this->setChildValue((itertemp->second),false);
}
if(isShow)
{
reText.push_back(m_PieValue[0]);
reText.push_back(m_PieValue[1]);
reText.push_back(m_PieValue[2]);
reText.push_back(m_PieValue[3]);
const char * tempID = getName().c_str();
if(isFind)
m_PieChartSelectInfo(tempID,PieType);
else
m_PieChartSelectInfo(tempID,-1);
}
return reText;
}
bool OsgPieChart::ConvertXYToLL(osg::Vec3 LBHbefor, osg::Vec3 offect, osg::Vec3& LBHafter)
{
// MapNode* pMapNode = m_pOsgEngine->GetMapNode();
// GeoPoint ConvertPoint;
// double lx,ly,lz;
// ConvertPoint.fromWorld(pMapNode->getMapSRS(),m_TempPoint1);
// m_pOsgEngine->convertLatLongHeightToXYZ(LBHbefor,)
// m_pOsgEngine->convertXYZToLatLongHeight(,lx,ly,lz);
return true;
}
void OsgPieChart::unicodeToUTF8( const std::wstring &src, std::string& result )
{
int n = WideCharToMultiByte( CP_UTF8, 0, src.c_str(), -1, 0, 0, 0, 0 );
result.resize(n);
::WideCharToMultiByte( CP_UTF8, 0, src.c_str(), -1, (char*)result.c_str(), result.length(), 0, 0 );
}
void OsgPieChart::gb2312ToUnicode( const std::string& src, std::wstring& result )
{
int n = MultiByteToWideChar( CP_ACP, 0, src.c_str(), -1, NULL, 0 );
result.resize(n);
::MultiByteToWideChar( CP_ACP, 0, src.c_str(), -1, (LPWSTR)result.c_str(), result.length());
}
void OsgPieChart::gb2312ToUtf8( const std::string& src,std::string&result )
{
wstring strWideChar;
gb2312ToUnicode(src, strWideChar);
unicodeToUTF8(strWideChar, result);
MultiByteToWideChar(CP_ACP,0,src.c_str(),-1,NULL,0);
}
osg::ref_ptr<osg::Group> OsgPieChart::createLights( osg::Vec3 posVec,osg::StateSet*rootstateset )
{
osg::ref_ptr<osg::Group> lightgroup = new osg::Group;
osg::ref_ptr<osg::Light> SpotLgt = new osg::Light;
SpotLgt->setLightNum(0);
SpotLgt->setPosition(osg::Vec4(posVec.x(),posVec.y(),posVec.z(),1.0f));
SpotLgt->setDiffuse(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
SpotLgt->setDirection(osg::Vec3(-posVec.x(),-posVec.y(),-posVec.z()));
osg::ref_ptr<osg::LightSource> lightS = new osg::LightSource;
lightS->setLight(SpotLgt);
lightS->setLocalStateSetModes(osg::StateAttribute::ON);
lightS->setStateSetModes(*rootstateset,osg::StateAttribute::ON);
lightgroup->addChild(lightS);
return lightgroup.release();
}
void OsgChartCallBack::operator()( osg::Node* node, osg::NodeVisitor* nv )
{
osgGA::EventVisitor* ev = static_cast<osgGA::EventVisitor*>(nv);
osgGA::EventVisitor::EventList& events = ev->getEvents();
osgViewer::View* view = static_cast<osgViewer::View*>(ev->getActionAdapter());
for( osgGA::EventVisitor::EventList::const_iterator e = events.begin(); e != events.end(); ++e )
{
osgGA::GUIEventAdapter* ea = e->get();
if ( ea->getEventType() == osgGA::GUIEventAdapter::FRAME || ea->getEventType() == osgGA::GUIEventAdapter::MOVE)
{
m_ChartNode->Pick(ea->getX(),ea->getY());
}
}
traverse(node, nv);
}
OsgChartCallBack::OsgChartCallBack( OsgPieChart*ChartNode )
:m_ChartNode(ChartNode)
{
}
OsgChartCallBack::~OsgChartCallBack()
{
}
void OsgChartUpdataCallBack::operator()( osg::Node* node, osg::NodeVisitor* nv )
{
if (!m_ChartNode)
{
traverse(node, nv);
return;
}
m_ChartNode->UpdataChart();
traverse(node, nv);
}
void EXPORT_DLL SetPieChartSelectItemInfoMsg( void* callback )
{
m_PieChartSelectInfo =(PieCharSelectItemInfoMsg)callback;
}
#pragma once
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include <osg/ShapeDrawable>
#include <osgEarthSymbology/Style>
#include <osgEarthAnnotation/OrthoNode>
#include <osg/Material>
#include <osgText/Text>
#include <osg/PagedLOD>
#include <osg/NodeCallback>
#include <osgEarthUtil/AnnotationEvents>
#include "OsgNodeBaseEvents.h"
#include "OsgGeodeEvents.h"
typedef void (*PieCharSelectItemInfoMsg)(const char* strID,int index);
using namespace osg;
using namespace osgEarth;
using namespace osgEarth::Util;
using namespace osgEarth::Annotation;
using namespace osgEarth::Symbology;
#define OSGPIECHART_R 0
#define OSGPIECHART_G 1
#define OSGPIECHART_B 2
#define OSGPIECHART_F 3
static PieCharSelectItemInfoMsg m_PieChartSelectInfo=NULL;
class OsgPieChart;
class OsgChartCallBack : public osg::NodeCallback
{
public:
OsgChartCallBack(OsgPieChart*ChartNode);
~OsgChartCallBack();
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
protected:
OsgPieChart* m_ChartNode; //对应统计图节点
};
class OsgChartUpdataCallBack : public osg::NodeCallback
{
public:
OsgChartUpdataCallBack(OsgPieChart*ChartNode):m_ChartNode(ChartNode)
{
}
~OsgChartUpdataCallBack(){}
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
protected:
OsgPieChart* m_ChartNode; //对应统计图节点
};
class OsgEarthEngine;
class OsgPieChart :public osg::Switch
{
public:
OsgPieChart(OsgEarthEngine* pOsgEngine, const osg::Vec3 xyz,double RVarlue=5,double GVarlue=5,double BVarlue=10,double FVarlue=10);
~OsgPieChart(void);
/**功能:画饼状图*/
void CreatePieChart(double PieRadius,double* PieValue);
/*功能:Chart大小调整(自适应屏幕)*/
bool AdpatRadioAndHeight(double& radio,double* height);
osg::ref_ptr<osg::Material> CreateMaterial();
/**功能:增加饼状图上的文字*/
osg::ref_ptr<osgText::Text> CreateText(std::string strText,osg::Vec3& vecPos,osg::Vec4 color=osg::Vec4(0.0,0.0,0.0,1.0),float size=20,std::string strFont=std::string("D:\\程序20151124\\simsunb.ttf"),osgText::Text::AlignmentType nAlign=osgText::Text::CENTER_BOTTOM);
osg::ref_ptr<OrthoNode> CreateTextQQ(std::string strText,osg::Vec3& vecPos,osgEarth::Annotation::Color color,int RGB=0);
/**功能:画扇形*/
osg::ref_ptr<osg::Geode> DrawSector(int PieType,osg::Vec3 vecCenter, float radius, float height, float startAngle, float endAngle, float delta,osgEarth::Annotation::Color vecColor,std::string strText=std::string(""));
/**功能:更新chart*/
void UpdataChart();
void GetPrecent(int PieType, std::string& Pre,double& startAngle,double& endAngle );
osg::ref_ptr<osg::MatrixTransform> getOrCreateText(int PieType,osg::Vec3& vecPos,std::string strText,osgEarth::Annotation::Color vecColor);
vector<double> ShowPieText(int PieType,bool isShow=true);
std::string GetStringPre(double PreNum);
osg::Vec3 ChangeLBH(float radius,float startAngle, float endAngle);
bool ConvertXYToLL(osg::Vec3 LBHbefor, osg::Vec3 offect, osg::Vec3& LBHafter);
void Pick(float x,float y );
osg::ref_ptr<osg::Group> createLights(osg::Vec3 posVec,osg::StateSet*rootstateset);
void unicodeToUTF8(const std::wstring &src, std::string& result);
void gb2312ToUnicode(const std::string& src, std::wstring& result);
void gb2312ToUtf8( const std::string& src,std::string&result);
protected:
std::string m_preSeleced;
int m_NodeID; //节点ID,在场景树中统计图集合的唯一标识
double m_preScale;
double m_Height;
osg::Vec3f m_LBH; //在球面上的经纬度和高程 B 纬度 L经度 H高程
//饼状图参数
double* m_PieValue;
double m_Pieradius;
OsgEarthEngine* m_pOsgEngine;
GDOGlobalEllipse* m_pGlobalEllipse;
osg::ref_ptr<osg::MatrixTransform> m_Mat;
OsgChartCallBack* m_PtCallback;
OsgChartUpdataCallBack* m_ptUpdataCallback;
public:
map<int,osg::ref_ptr<osg::MatrixTransform>> m_TextVec;
};
#define EXPORT_DLL __declspec(dllexport)
#ifdef __cplusplus
extern "C"
{
#endif
void EXPORT_DLL SetPieChartSelectItemInfoMsg(void* callback);
#ifdef __cplusplus
}
#endif