osgEarth中绘制圆

osgEarth3.2+qt5.14+osg3.6.5

#ifndef CIRCLEDRAWER_H
#define CIRCLEDRAWER_H
#include <osgEarth/MapNode>
#include <osgEarth/Geometry>
#include <osgEarth/GeoMath>
#include <osgEarth/CircleNode>
#include <osgEarth/Style>

#include <osgViewer/Viewer>
#include <osgGA/GUIEventHandler>

#include <vector>
class CircleDrawer: public osgGA::GUIEventHandler
{
public:
    CircleDrawer( osg::ref_ptr<osgEarth::MapNode> mapNode);
    ~CircleDrawer();

    void removeSelectCircle(osg::ref_ptr<osg::Node> node);

    void removeCircle();

    void removeAllCircles();

    void createPieSegment();

    void createCircle(osg::Vec3d position,double radiusCir);

    //获取绘制状态
    bool getIsDrawCir();

    //设置绘制状态
    void setIsDrawCir(bool isDraw);
    //事件处理
    bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa);
private:
    osg::ref_ptr<osgEarth::MapNode> _mapNode;
    osg::ref_ptr<osgEarth::CircleNode> _circleNode;
    osgEarth::Style _circleStyle;       // 样式
    bool isDrawCir;                     //开启绘制圆
    bool isDeletDrawCir;                //开启删除圆
    double radiusCir;                   //圆半径
    osg::NodePath   nodePaths;
    std::vector<osg::ref_ptr<osgEarth::CircleNode>> _circleNodes; // 保存所有绘制的矩形
};

#endif // CIRCLEDRAWER_H

#include "CircleDrawer.h"
CircleDrawer::CircleDrawer(osg::ref_ptr<osgEarth::MapNode> mapNode)
    :_mapNode(mapNode)
    ,_circleNode(nullptr)
    ,isDrawCir(false)
    ,isDeletDrawCir(true)
    ,radiusCir(500.0)
{
    _circleStyle.getOrCreate<osgEarth::PolygonSymbol>()->fill()->color() = osgEarth::Color(osgEarth::Color::Yellow, 0.25); // 黄色半透明
    nodePaths.push_back(mapNode);
}
CircleDrawer::~CircleDrawer()
{

}
void CircleDrawer::removeSelectCircle(osg::ref_ptr<osg::Node> node)
{
    _mapNode->removeChild(node); // 从地图中移除
}

void CircleDrawer::removeCircle()
{
    if (!_circleNodes.empty()) {
        osg::ref_ptr<osgEarth::CircleNode> lastNode = _circleNodes.back();
        _mapNode->removeChild(lastNode); // 从地图中移除
        _circleNodes.pop_back();     // 从列表中移除
    }
}

void CircleDrawer::removeAllCircles()
{
    for (auto& node : _circleNodes) {
       _mapNode->removeChild(node); // 从地图中移除
    }
    _circleNodes.clear(); // 清空列表
}
bool CircleDrawer::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
{
    if (!_mapNode)
        return false;

    osgViewer::Viewer *viewer = dynamic_cast<osgViewer::Viewer *>(&aa);
    if (!viewer)
        return false;

    if (!isDrawCir)
        return false;

    switch (ea.getEventType()) {
        case osgGA::GUIEventAdapter::PUSH: {
            switch (ea.getButton()) {
                case osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON: {
                    osgUtil::LineSegmentIntersector::Intersections intersections;
                    if (viewer->computeIntersections(ea.getX(), ea.getY(), nodePaths, intersections)) {
                        const osgUtil::LineSegmentIntersector::Intersection &intersection = *intersections.begin();
                        osg::Vec3d worldPoint = intersection.getWorldIntersectPoint();

                        const osgEarth::SpatialReference *mapSRS = _mapNode->getMapSRS();
                        const osgEarth::SpatialReference *geoSRS = osgEarth::SpatialReference::get("wgs84");
                        osgEarth::GeoPoint geoPoint;
                        geoPoint.fromWorld(mapSRS, worldPoint);
                        osgEarth::GeoPoint wgs84Point;
                        geoPoint.transform(geoSRS, wgs84Point);

                        double lon = wgs84Point.x();
                        double lat = wgs84Point.y();
                        double height = wgs84Point.z();

                        osgEarth::GeoPoint position(geoSRS, lon, lat, height, osgEarth::AltitudeMode::ALTMODE_RELATIVE);
                        osg::ref_ptr<osgEarth::CircleNode> circleNode = new osgEarth::CircleNode();
                        circleNode->set(position, osgEarth::Distance(radiusCir, osgEarth::Units::METERS), _circleStyle);
                        circleNode->setName("CirCle");
                        _circleNode = circleNode;
                        _circleNodes.push_back(_circleNode);
                        _mapNode->addChild(_circleNode);
                    }
                    break;
                }
                case osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON: {
                    osg::ref_ptr<osg::Node> node = NULL;
                    osgUtil::LineSegmentIntersector::Intersections intersections;
                    if (viewer->computeIntersections(ea.getX(), ea.getY(), nodePaths, intersections)) {
                        for (const auto &intersection : intersections) {
                            for (auto i : intersection.nodePath) {
                                if (i->getName().find("CirCle") != std::string::npos) {
                                    node = i;
                                    break;
                                }
                            }
                            if (node)
                                break;
                        }
                    }
                    if (node) {
                        removeSelectCircle(node);
                    }
                    break;
                }
            }
            break;
        }
        case osgGA::GUIEventAdapter::KEYDOWN: {
            switch (ea.getKey()) {
                case osgGA::GUIEventAdapter::KEY_Delete:
                    removeCircle();
                    break;
                case osgGA::GUIEventAdapter::KEY_BackSpace:
                    removeAllCircles();
                    break;
                default:
                   std::cerr << "Warning: Unhandled mouse button event." << std::endl;
                   break;
            }
            break;
        }
        default:
            break;
    }
    return false;
}


//绘制扇形的例子
void CircleDrawer::createPieSegment()
{
    // 定义圆的样式
    osgEarth::Style circleStyle;
    osgEarth::LineSymbol* line = circleStyle.getOrCreate<osgEarth::LineSymbol>();
    line->stroke()->color() = osgEarth::Color::Yellow;  // 设置边框颜色为黄色
    line->stroke()->width() = 2.0f;           // 设置边框宽度
    line->stroke()->smooth() = true;          // 抗锯齿
    // (配置样式细节, 例如填充颜色、边框等)
    osgEarth::PolygonSymbol* polygon = circleStyle.getOrCreate<osgEarth::PolygonSymbol>();
       polygon->fill()->color() = osgEarth::Color(1.0, 0.0, 0.0, 0.5);  // 半透明红色
    // 定义圆心位置
    const osgEarth::SpatialReference* geoSRS = osgEarth::SpatialReference::get("wgs84"); // WGS84 地理坐标系
    osgEarth::GeoPoint position(
        geoSRS,
        109.002,   // 经度
        23.519,   // 纬度
        60,   // 高度
        osgEarth::AltitudeMode::ALTMODE_RELATIVE
    );

    // 定义半径
    osgEarth::Distance radius(100, osgEarth::Units::METERS);

    // 创建 CircleNode
    osgEarth::CircleNode* circleNode = new osgEarth::CircleNode();
    circleNode->set(
        position,               // 圆心位置
        radius,                 // 半径
        circleStyle,            // 样式
        osgEarth::Angle(0.0, osgEarth::Units::DEGREES),   // 起始角度
        osgEarth::Angle(45.0, osgEarth::Units::DEGREES),  // 终止角度
        true                    // 是否为扇形
    );

    // 将 CircleNode 添加到地图节点
    _mapNode->addChild(circleNode);
}

//绘制圆
void CircleDrawer::createCircle(osg::Vec3d position,double radiusCir)
{
    osgEarth::Style circleStyle;
    osgEarth::PolygonSymbol* polygon = circleStyle.getOrCreate<osgEarth::PolygonSymbol>();
    polygon->fill()->color() = osgEarth::Color(osgEarth::Color::Yellow, 0.25);
    const osgEarth::SpatialReference* geoSRS = osgEarth::SpatialReference::get("wgs84"); // WGS84 地理坐标系
    osgEarth::GeoPoint positions(geoSRS, position.x(), position.y(), 80, osgEarth::AltitudeMode::ALTMODE_RELATIVE);
    osg::ref_ptr<osgEarth::CircleNode> circleNode = new osgEarth::CircleNode();
    circleNode->set(positions,osgEarth::Distance(radiusCir, osgEarth::Units::METERS),circleStyle);
    circleNode->setName("CirCle");
    _circleNode=circleNode;
    // 保存到列表中
    _circleNodes.push_back(_circleNode);
    _mapNode->addChild(_circleNode);
}

bool CircleDrawer::getIsDrawCir()
{
    return isDrawCir;
}

void CircleDrawer::setIsDrawCir(bool isDraw)
{
    isDrawCir=isDraw;
}

参考代码链接
29 235G

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值