0
点赞
收藏
分享

微信扫一扫

osgearth标注

若如初梘 2022-03-11 阅读 78
#include<Windows.h>
#include <osgEarth/MapNode>

#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/ExampleResources>

#include <osgEarthAnnotation/ImageOverlay>
#include <osgEarthAnnotation/CircleNode>
#include <osgEarthAnnotation/RectangleNode>
#include <osgEarthAnnotation/EllipseNode>
#include <osgEarthAnnotation/PlaceNode>
#include <osgEarthAnnotation/LabelNode>
#include <osgEarthAnnotation/LocalGeometryNode>
#include <osgEarthAnnotation/FeatureNode>

#include <osgEarthAnnotation/AnnotationEditing>
#include <osgEarthAnnotation/ImageOverlayEditor>

#include <osgEarthSymbology/GeometryFactory>

#include <osgViewer/Viewer>
#include<string>

//键盘事件
#include<osgViewer/ViewerEventHandlers>
//osgGA相关的库
#include<osgGA/StateSetManipulator>

using namespace osgEarth;
using namespace osgEarth::Annotation;
using namespace osgEarth::Features;
using namespace osgEarth::Util;

void 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);
}

int main(int argc, char** argv)
{
	//调用设置osg的打印等级为0,不打印
	osg::setNotifyLevel(osg::NotifySeverity::ALWAYS);

    osg::Group* root = new osg::Group();
    osgViewer::Viewer viewer;
	//添加状态事件,可以相应键盘和鼠标事件,响应L T B W
	viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
	//窗口大小变化,响应F
	viewer.addEventHandler(new osgViewer::WindowSizeHandler);
	//添加路径记录 Z
	viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);
	//帮助文档显示H
	viewer.addEventHandler(new osgViewer::HelpHandler);
	//截屏 C
	viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
	//添加一些常用状态设置,响应S
	viewer.addEventHandler(new osgViewer::StatsHandler);
    viewer.setCameraManipulator( new EarthManipulator() );
	osg::Node* node = osgDB::readNodeFile("clear_terrain.earth");
    root->addChild( node );

    MapNode* mapNode = MapNode::findMapNode(node);

    osg::Group* annoGroup = new osg::Group();
    root->addChild( annoGroup );

    // Make a group for labels
    osg::Group* labelGroup = new osg::Group();
    annoGroup->addChild( labelGroup );

    osg::Group* editGroup = new osg::Group();
    root->addChild( editGroup );

    // Style our labels:
    Style labelStyle;
    labelStyle.getOrCreate<TextSymbol>()->alignment() = TextSymbol::ALIGN_CENTER_CENTER;
    labelStyle.getOrCreate<TextSymbol>()->fill()->color() = Color::Yellow;
	labelStyle.getOrCreate<TextSymbol>()->font() = "simhei.ttf";
	labelStyle.getOrCreate<TextSymbol>()->encoding() = osgEarth::Symbology::TextSymbol::ENCODING_UTF8;

    // A lat/long SRS for specifying points.
    const SpatialReference* geoSRS = mapNode->getMapSRS()->getGeographicSRS();

    //--------------------------------------------------------------------

    //label
    {
        Style pm;
        pm.getOrCreate<IconSymbol>()->url()->setLiteral( "../data/placemark32.png" );
        pm.getOrCreate<IconSymbol>()->declutter() = true;
        pm.getOrCreate<TextSymbol>()->halo() = Color("#5f5f5f");
		pm.getOrCreate<TextSymbol>()->font() = "simhei.ttf";
		pm.getOrCreate<TextSymbol>()->encoding() = osgEarth::Symbology::TextSymbol::ENCODING_UTF8;

        // bunch of pins:
		std::string beijing, shanghai, xian, wuhan, shenzhen, chengdu,shangluo,lasa, kunming, nanjing,
			wulumuqi, huhehaote;
		unicodeToUTF8(L"北京",beijing);
		unicodeToUTF8(L"上海", shanghai);
		unicodeToUTF8(L"西安", xian);
		unicodeToUTF8(L"武汉", wuhan);
		unicodeToUTF8(L"深圳", shenzhen);
		unicodeToUTF8(L"成都", chengdu);
		unicodeToUTF8(L"商洛", shangluo);
		unicodeToUTF8(L"拉萨", lasa);
		unicodeToUTF8(L"昆明", kunming);
		unicodeToUTF8(L"南京", nanjing);
		unicodeToUTF8(L"乌鲁木齐", wulumuqi);
		unicodeToUTF8(L"呼和浩特", huhehaote);

        labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 116.46, 39.92), beijing, pm));
        labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 121.48, 121.48), shanghai, pm));
        labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 108.95, 34.27), xian , pm));
        labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 114.31, 30.52), wuhan  , pm));
        labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 114.06, 22.62), shenzhen  , pm));
        labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 104.07, 30.67), chengdu  , pm));
		labelGroup->addChild(new PlaceNode(mapNode, GeoPoint(geoSRS, 102.72, 25.05), kunming, pm));
		labelGroup->addChild(new PlaceNode(mapNode, GeoPoint(geoSRS, 118.78, 32.07), nanjing, pm));
		labelGroup->addChild(new PlaceNode(mapNode, GeoPoint(geoSRS, 87.68, 43.77), wulumuqi, pm));
		labelGroup->addChild(new LabelNode(mapNode, GeoPoint(geoSRS, 111.73, 40.83), huhehaote, labelStyle));
        // test with an LOD:
        osg::LOD* lod = new osg::LOD();
        lod->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 109.93, 33.87), shangluo, pm), 0.0, 2e6);
        labelGroup->addChild( lod );

        // absolute altitude:
        labelGroup->addChild( new PlaceNode(mapNode, GeoPoint(geoSRS, 91.13, 29.65, 1000, ALTMODE_ABSOLUTE), lasa, pm));
    }

    //--------------------------------------------------------------------

    // 多边形
    {
        Geometry* geom = new osgEarth::Symbology::Polygon();
		geom->push_back(osg::Vec3d(95.0, 30.0, 0));
		geom->push_back(osg::Vec3d(100.0, 30.0, 0));
		geom->push_back(osg::Vec3d(100.0, 40.0, 0));
		geom->push_back(osg::Vec3d(95.0, 40.0, 0));

		osgEarth::Features::Feature* feature = new osgEarth::Features::Feature(geom, geoSRS);
        //插值类型
		feature->geoInterp() = GEOINTERP_RHUMB_LINE;

        Style geomStyle;
        geomStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::Cyan;
        geomStyle.getOrCreate<LineSymbol>()->stroke()->width() = 5.0f;
        geomStyle.getOrCreate<LineSymbol>()->tessellationSize() = 75000;
        geomStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;
        geomStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU;
        
        FeatureNode* fnode = new FeatureNode(mapNode, feature, geomStyle);
        
        annoGroup->addChild( fnode );
    }

    //--------------------------------------------------------------------

    // 多边形
    {
        Geometry* geom = new osgEarth::Symbology::Polygon();
        geom->push_back( -160., -30. );
        geom->push_back(  150., -20. );
        geom->push_back(  160., -45. );
        geom->push_back( -150., -40. );
        Style geomStyle;

        Feature* feature = new Feature(geom, geoSRS);
        feature->geoInterp() = GEOINTERP_RHUMB_LINE;

        geomStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::Lime;
        geomStyle.getOrCreate<LineSymbol>()->stroke()->width() = 3.0f;
        geomStyle.getOrCreate<LineSymbol>()->tessellationSize() = 75000;
        geomStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;
        geomStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU;

        FeatureNode* gnode = new FeatureNode(mapNode, feature, geomStyle);
        annoGroup->addChild( gnode );

        labelGroup->addChild( new LabelNode(mapNode, GeoPoint(geoSRS, 105, 35), "Antimeridian polygon", labelStyle) );
    }

    //--------------------------------------------------------------------



	//线
    FeatureNode* pathNode = 0;
    {
        Geometry* path = new LineString();
        path->push_back( osg::Vec3d(108.95, 34.27, 0) );//西安
        path->push_back( osg::Vec3d(116.46, 39.92, 0) );//北京

        Feature* pathFeature = new Feature(path, geoSRS);
        pathFeature->geoInterp() = GEOINTERP_GREAT_CIRCLE;

        Style pathStyle;
        pathStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::White;
        pathStyle.getOrCreate<LineSymbol>()->stroke()->width() = 1.0f;
		//对线几何进行曲面细分,使任何线段的长度都不会超过此值
        pathStyle.getOrCreate<LineSymbol>()->tessellationSize() = 75000;
        //pathStyle.getOrCreate<PointSymbol>()->size() = 5;
        //pathStyle.getOrCreate<PointSymbol>()->fill()->color() = Color::Red;
        pathStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;
        pathStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU;

        //OE_INFO << "Path extent = " << pathFeature->getExtent().toString() << std::endl;

        pathNode = new FeatureNode(mapNode, pathFeature, pathStyle);
        annoGroup->addChild( pathNode );

        //labelGroup->addChild( new LabelNode(mapNode, GeoPoint(geoSRS,112.705, 37.095), "Great circle path", labelStyle) );
    }

    //--------------------------------------------------------------------

    // 圆
    {
        Style circleStyle;
        circleStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Cyan, 0.5);//青色
        circleStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;
        circleStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE;

        CircleNode* circle = new CircleNode(
            mapNode,
            GeoPoint(geoSRS, 118.78, 32.07, 1000., ALTMODE_RELATIVE),//南京
            Distance(300, Units::KILOMETERS), //半径
            circleStyle, Angle(-45.0, Units::DEGREES), Angle(45.0, Units::DEGREES), true);
        annoGroup->addChild( circle );

        editGroup->addChild( new CircleNodeEditor(circle) );
    }

	{
		Style circleStyle;
		circleStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Red, 0.5);
		circleStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;
		circleStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE;

		CircleNode* circle = new CircleNode(
			mapNode,
			GeoPoint(geoSRS, 118.78, 32.07, 1000., ALTMODE_RELATIVE),//南京
			Distance(300, Units::KILOMETERS),
			circleStyle, Angle(45.0, Units::DEGREES), Angle(360.0 - 45.0, Units::DEGREES), true);
		annoGroup->addChild( circle );

        editGroup->addChild( new CircleNodeEditor(circle) );
	}

    //--------------------------------------------------------------------

    // 立体椭圆
    {
        Style ellipseStyle;
        ellipseStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Orange, 0.75);
        ellipseStyle.getOrCreate<ExtrusionSymbol>()->height() = 25000.0; // meters MSL
        osgEarth::Annotation::EllipseNode* ellipse = new osgEarth::Annotation::EllipseNode(
            mapNode, 
            GeoPoint(geoSRS, 102.72, 25.05, 0.0, ALTMODE_RELATIVE),//云南
            Distance(250, Units::MILES),
            Distance(100, Units::MILES),
            Angle   (0, Units::DEGREES),
            ellipseStyle,
            Angle(45.0, Units::DEGREES),
            Angle(360.0 - 45.0, Units::DEGREES), 
            true);
        annoGroup->addChild( ellipse );
        editGroup->addChild( new EllipseNodeEditor(ellipse) );

		//CircleNode
		Style circleStyle;
		circleStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Orange, 0.75);
		circleStyle.getOrCreate<ExtrusionSymbol>()->height() = 25000.0; // meters MSL
		osgEarth::Annotation::CircleNode* circle = new osgEarth::Annotation::CircleNode(
			mapNode,
			GeoPoint(geoSRS, 102.72, 25.05, 0.0, ALTMODE_RELATIVE),
			Distance(250, Units::MILES),
			circleStyle,
			Angle(45.0, Units::DEGREES),
			Angle(360.0 - 45.0, Units::DEGREES)
			);
		//annoGroup->addChild(circle);
		//editGroup->addChild(new CircleNodeEditor(circle));
    }
	{
		Style ellipseStyle;
		ellipseStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Blue, 0.75);
		ellipseStyle.getOrCreate<ExtrusionSymbol>()->height() = 25000.0; // meters MSL
		EllipseNode* ellipse = new EllipseNode(
			mapNode, 
			GeoPoint(geoSRS, 102.72, 25.05, 0.0, ALTMODE_RELATIVE),
			Distance(250, Units::MILES),
			Distance(100, Units::MILES),
			Angle   (0, Units::DEGREES),
			ellipseStyle, 
            Angle(-40.0, Units::DEGREES), 
            Angle(40.0, Units::DEGREES), 
            true);
		annoGroup->addChild( ellipse );

        editGroup->addChild( new EllipseNodeEditor(ellipse) );
	}
    
    //--------------------------------------------------------------------

    {
        // 矩形
        Style rectStyle;
        rectStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Green, 0.5);
        rectStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;
        rectStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE;
        RectangleNode* rect = new RectangleNode(
            mapNode, 
            GeoPoint(geoSRS, 87.68, 43.77),//乌鲁木齐
            Distance(300, Units::KILOMETERS ),
            Distance(600, Units::KILOMETERS ),
            rectStyle);
        annoGroup->addChild( rect );

        editGroup->addChild( new RectangleNodeEditor(rect) );
    }    

    //--------------------------------------------------------------------

    //立体拉伸多边形
    {
        Geometry* utah = new osgEarth::Symbology::Polygon();
        utah->push_back( 114.052, 37.0   );
        utah->push_back( 109.054, 37.0   );
        utah->push_back( 109.054, 41.0   );
        utah->push_back( 111.040, 41.0   );
        utah->push_back( 111.080, 42.059 );
        utah->push_back( 114.080, 42.024 );

        Style utahStyle;
        utahStyle.getOrCreate<ExtrusionSymbol>()->height() = 250000.0; // meters MSL
        utahStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::White, 0.8);

        Feature*     utahFeature = new Feature(utah, geoSRS);
        FeatureNode* featureNode = new FeatureNode(mapNode, utahFeature, utahStyle);
        annoGroup->addChild( featureNode );
    }

    //--------------------------------------------------------------------

    // 贴图
    {
        ImageOverlay* imageOverlay = 0L;
        osg::Image* image = osgDB::readImageFile( "china.png" );
        if ( image )
        {
            imageOverlay = new ImageOverlay(mapNode, image);
            imageOverlay->setBounds( Bounds( 115, 39, 116, 40.0) );// 左下 右上
            annoGroup->addChild( imageOverlay );
            editGroup->addChild( new ImageOverlayEditor(imageOverlay) );
        }
    }

    //--------------------------------------------------------------------

    // initialize the viewer:    
    viewer.setSceneData( root );    
    viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f);
    return viewer.run();
}
 

 

 

举报

相关推荐

0 条评论