osgearth-osgEarthUtil-MeasureTool handle代码解析

来源:互联网 发布:rx480吃鸡优化 编辑:程序博客网 时间:2024/05/16 03:55
bool MeasureToolHandler::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )

{   

    if ( ea.getHandled() )

    {

        returnfalse;

    }

 

 

    osgViewer::View* view = static_cast<osgViewer::View*>(aa.asView());

 

    //左键一直按下,_mouseDown区分开鼠标左键是否长按

    if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH && ea.getButton() == _mouseButton)

    {       

        _mouseDown = true;

        _mouseDownX = ea.getX();

        _mouseDownY = ea.getY();

    }

    //左键释放

    elseif (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && ea.getButton() == _mouseButton)

    {       

        float eps = 1.0f;

        _mouseDown = false;

        //判定鼠标左键按下并释放时,屏幕位置是否相同

        if (osg::equivalent(ea.getX(), _mouseDownX) && osg::equivalent(ea.getY(), _mouseDownY))

        {

            //相同——单击情况如下

            //获取鼠标点击位置的经纬度

            double lon, lat;

            if (getLocationAt(view, ea.getX(), ea.getY(), lon, lat))

            {

                if (!_gotFirstLocation)//获取第一个点击点

                {

                    _finished = false;//取点结束状态为假

                    clear(); //清除所画路径                  

                    _gotFirstLocation = true;//表示已经获得第一个点

                    _feature->getGeometry()->push_back( osg::Vec3d( lon, lat, 0 ) );//压入矢量点

                }

                else//第一个点已经获取完毕

                {

                    if (_lastPointTemporary)//如果是暂存的最后一个点

                    {

                        //将此点压入矢量点

                        _feature->getGeometry()->back() = osg::Vec3d( lon, lat, 0 );

                        //暂存的最后一个点状态为false

                        _lastPointTemporary = false;

                    }

                    else//如果是不是暂存的最后一个点

                    {                    

                        _feature->getGeometry()->push_back( osg::Vec3d( lon, lat, 0 ) );

                    }

                    //初始化featureNode

                    _featureNode->init();

 

                    //_gotFirstLocation = false;

                    //_finished = true;

                    //如果绘制结束或者画的是不是多条线段

                    if (_finished || !_isPath) {

                        _gotFirstLocation = false;//获取第一点为假

                    }

 

#ifdef SHOW_EXTENT

                    const GeoExtent ex( _feature->getSRS(), _feature->getGeometry()->getBounds() );

                    //OE_INFO << "extent = " << ex.toString() << std::endl;

                    Geometry* eg = _extentFeature->getGeometry();

                    osg::Vec3d fc = ex.getCentroid();

                    eg->clear();

                    eg->push_back( ex.west(), ex.south() );

                    if ( ex.width() >= 180.0 )

                        eg->push_back( fc.x(), ex.south() );

                    eg->push_back( ex.east(), ex.south() );

                    eg->push_back( ex.east(), ex.north() );

                    if ( ex.width() >= 180.0 )

                        eg->push_back( fc.x(), ex.north() );

                    eg->push_back( ex.west(), ex.north() );

                    _extentFeatureNode->init();

#endif

 

                    fireDistanceChanged();

                    //触发重绘事件

                    aa.requestRedraw();

                }

            }

        }

    } 

    elseif (ea.getEventType() == osgGA::GUIEventAdapter::DOUBLECLICK) {       

        if (_gotFirstLocation)//如果得到第一个点为真

        {

            //_gotFirstLocation = false;

            _finished = true;    //结束绘制

            aa.requestRedraw(); //重绘

            returntrue;

        }

    }

    elseif (ea.getEventType() == osgGA::GUIEventAdapter::MOVE)

    {

        if (_gotFirstLocation)//如果得到第一个点为真

        {

            double lon, lat;

            if (getLocationAt(view, ea.getX(), ea.getY(), lon, lat))

            {

                //如果最后一点暂存点为假

                if (!_lastPointTemporary)

                {

                    _feature->getGeometry()->push_back( osg::Vec3d( lon, lat, 0 ) );                 

                    _lastPointTemporary = true;

                }                       

                else

                {

                    _feature->getGeometry()->back() = osg::Vec3d( lon, lat, 0 );

                }

                _featureNode->init();

                fireDistanceChanged();

                aa.requestRedraw();

            }

        }

    }   

    returnfalse;

}

//获取屏幕所在点的世界坐标系坐标

bool MeasureToolHandler::getLocationAt(osgViewer::View* view, double x, double y, double &lon, double &lat)

{

    osgUtil::LineSegmentIntersector::Intersections results;           

    if ( getMapNode() &&  view->computeIntersections( x, y, results, _intersectionMask ) )

    {

        // find the first hit under the mouse:

        osgUtil::LineSegmentIntersector::Intersection first = *(results.begin());

        osg::Vec3d point = first.getWorldIntersectPoint();

 

        double lat_rad, lon_rad, height;      

        getMapNode()->getMap()->getProfile()->getSRS()->getEllipsoid()->convertXYZToLatLongHeight(

            point.x(), point.y(), point.z(), lat_rad, lon_rad, height );

 

        lat = osg::RadiansToDegrees( lat_rad );

        lon = osg::RadiansToDegrees( lon_rad );

        returntrue;

    }

    returnfalse;

}

 

 

 


0 0