void
CircleNodeEditor::updateDraggers()
{
    LocalizedNodeEditor::updateDraggers();
    if (_radiusDragger)
    {
        const osg::EllipsoidModel* em = _node->getMapNode()->getMapSRS()->getEllipsoid();
        
        // Get the current location of the center of the circle (in lat/long, absolute Z)
        GeoPoint location = _node->getPosition();   
        location.makeGeographic();
        //location.makeAbsolute( _node->getMapNode()->getTerrain() );
        
        //Get the radius of the circle in meters
        double r = static_cast<CircleNode*>(_node.get())->getRadius().as(Units::METERS);

        double lat, lon;
        GeoMath::destination(
            osg::DegreesToRadians( location.y() ), osg::DegreesToRadians( location.x() ), 
            _bearing, r, lat, lon, em->getRadiusEquator() );

        GeoPoint draggerLocation( 
            location.getSRS(),
            osg::RadiansToDegrees(lon),
            osg::RadiansToDegrees(lat));

        draggerLocation.z() = 0;

        _radiusDragger->setPosition( draggerLocation, false );
    }
}
Esempio n. 2
0
void
LabelNode::updateLayoutData()
{
    if (!_dataLayout.valid())
    {
        _dataLayout = new ScreenSpaceLayoutData();
    }

    // re-apply annotation drawable-level stuff as neccesary.
    for (unsigned i = 0; i < _geode->getNumChildren(); ++i)
    {
        _geode->getChild(i)->setUserData(_dataLayout.get());
    }
    
    _dataLayout->setPriority(getPriority());
    
    GeoPoint location = getPosition();
    location.makeGeographic();
    double latRad;
    double longRad;
    GeoMath::destination(osg::DegreesToRadians(location.y()),
        osg::DegreesToRadians(location.x()),
        _labelRotationRad,
        2500.,
        latRad,
        longRad);

    _geoPointProj.set(osgEarth::SpatialReference::get("wgs84"),
        osg::RadiansToDegrees(longRad),
        osg::RadiansToDegrees(latRad),
        0,
        osgEarth::ALTMODE_ABSOLUTE);

    _geoPointLoc.set(osgEarth::SpatialReference::get("wgs84"),
        //location.getSRS(),
        location.x(),
        location.y(),
        0,
        osgEarth::ALTMODE_ABSOLUTE);

    const TextSymbol* ts = getStyle().get<TextSymbol>();
    if (ts)
    {
        _dataLayout->setPixelOffset(ts->pixelOffset().get());
        
        if (_followFixedCourse)
        {
            osg::Vec3d p0, p1;
            _geoPointLoc.toWorld(p0);
            _geoPointProj.toWorld(p1);
            _dataLayout->setAnchorPoint(p0);
            _dataLayout->setProjPoint(p1);
        }
    }
}
Esempio n. 3
0
std::string
LatLongFormatter::format( const GeoPoint& p ) const
{
    GeoPoint geo = p;
    if ( !geo.makeGeographic() )
        return "";

    return Stringify()
        << format( Angular(geo.y()) )
        << ", "
        << format( Angular(geo.x()) );
}
      virtual void onPositionChanged(const Dragger* sender, const osgEarth::GeoPoint& position)
      {
          const osg::EllipsoidModel* em = _node->getMapNode()->getMapSRS()->getEllipsoid();

          GeoPoint radiusLocation(position);
          radiusLocation.makeGeographic();

          //Figure out the distance between the center of the circle and this new location
          GeoPoint center = _node->getPosition();
          center.makeGeographic();

          double distance = GeoMath::distance(osg::DegreesToRadians( center.y() ), osg::DegreesToRadians( center.x() ), 
                                              osg::DegreesToRadians( radiusLocation.y() ), osg::DegreesToRadians( radiusLocation.x() ),
                                              em->getRadiusEquator());
          _node->setRadius( Linear(distance, Units::METERS ) );
          //The position of the radius dragger has changed, so recompute the bearing
          _editor->computeBearing();
      }
void
CircleNodeEditor::computeBearing()
{
    _bearing = osg::DegreesToRadians( 90.0 );
    //Get the radius dragger's position
    if (!_radiusDragger->getMatrix().isIdentity())
    {
        // Get the current location of the center of the circle (in lat/long)
        GeoPoint location = _node->getPosition();
        location.makeGeographic();

        // location of the radius dragger (in lat/long)
        GeoPoint radiusLocation;
        radiusLocation.fromWorld( location.getSRS(), _radiusDragger->getMatrix().getTrans() );

        // calculate the bearing b/w the 
        _bearing = GeoMath::bearing(
            osg::DegreesToRadians(location.y()), osg::DegreesToRadians(location.x()),
            osg::DegreesToRadians(radiusLocation.y()), osg::DegreesToRadians(radiusLocation.x()));
    }
}
Esempio n. 6
0
bool
MGRSFormatter::transform( const GeoPoint& input, MGRSCoord& out ) const
{
    if ( !input.isValid() )
        return false;

    // convert to lat/long if necessary:
    GeoPoint inputGeo = input;
    if ( !inputGeo.makeGeographic() )
        return false;

    unsigned    zone;
    char        gzd;
    unsigned    x=0, y=0;
    char        sqid[3];
    std::string space;

    if ( _options & USE_SPACES )
        space = " ";

    sqid[0] = '?';
    sqid[1] = '?';
    sqid[2] = 0;

    double latDeg = inputGeo.y();
    double lonDeg = inputGeo.x();

    if ( latDeg >= 84.0 || latDeg <= -80.0 ) // polar projection
    {
        bool isNorth = latDeg > 0.0;
        zone = 0;
        gzd = isNorth ? (lonDeg < 0.0 ? 'Y' : 'Z') : (lonDeg < 0.0? 'A' : 'B');

        osg::ref_ptr<const SpatialReference> ups =
            const_cast<MGRSFormatter*>(this)->_srsCache[ s_polarZoneSpecs[isNorth?0:1] ];
        if (!ups.valid())
            ups = SpatialReference::create( s_polarZoneSpecs[isNorth?0:1] );

        if ( !ups.valid() )
        {
            OE_WARN << LC << "Failed to create UPS SRS" << std::endl;
            return false;
        }

        osg::Vec3d upsCoord;
        if ( _refSRS->transform(osg::Vec3d(lonDeg,latDeg,0), ups.get(), upsCoord) == false )
        {
            OE_WARN << LC << "Failed to transform lat/long to UPS" << std::endl;
            return false;
        }

        int sqXOffset = upsCoord.x() >= 0.0 ? (int)floor(upsCoord.x()/100000.0) : -(int)floor(1.0-(upsCoord.x()/100000.0));
        int sqYOffset = upsCoord.y() >= 0.0 ? (int)floor(upsCoord.y()/100000.0) : -(int)floor(1.0-(upsCoord.y()/100000.0));

        int alphaOffset = isNorth ? 7 : 12;

        sqid[0] = UPS_COL_ALPHABET[ (UPS_COL_ALPHABET_SIZE+sqXOffset) % UPS_COL_ALPHABET_SIZE ];
        sqid[1] = UPS_ROW_ALPHABET[alphaOffset + sqYOffset];

        x = (unsigned)(upsCoord.x() - (100000.0*(double)sqXOffset));
        y = (unsigned)(upsCoord.y() - (100000.0*(double)sqYOffset));
    }

    else // UTM
    {
        // figure out the grid zone designator
        unsigned gzdIndex = ((unsigned)(latDeg+80.0))/8;
        gzd = GZD_ALPHABET[gzdIndex];

        // figure out the UTM zone:
        zone = (unsigned)floor((lonDeg+180.0)/6.0);   // [0..59]
        bool north = latDeg >= 0.0;

        // convert the input coordinates to UTM:
        // yes, always use +north so we get Y relative to equator

        // using an SRS cache speed things up a lot..
        osg::ref_ptr<const SpatialReference>& utm =
            const_cast<MGRSFormatter*>(this)->_srsCache[s_lateralZoneSpecs[zone]];
        if ( !utm.valid() )
            utm = SpatialReference::create( s_lateralZoneSpecs[zone] );

        osg::Vec3d utmCoord;
        if ( _refSRS->transform( osg::Vec3d(lonDeg,latDeg,0), utm.get(), utmCoord) == false )
        {
            OE_WARN << LC << "Error transforming lat/long into UTM" << std::endl;
            return false;
        }

        // the alphabet set:
        unsigned set = zone % 6; // [0..5]

        // find the horizontal SQID offset (100KM increments) from the central meridian:
        unsigned xSetOffset = 8 * (set % 3);
        double xMeridianOffset = utmCoord.x() - 500000.0;
        int sqMeridianOffset = xMeridianOffset >= 0.0 ? (int)floor(xMeridianOffset/100000.0) : -(int)floor(1.0-(xMeridianOffset/100000.0));
        unsigned indexOffset = (4 + sqMeridianOffset);
        sqid[0] = UTM_COL_ALPHABET[xSetOffset + indexOffset];
        double xWest = 500000.0 + (100000.0*(double)sqMeridianOffset);
        x = (unsigned)(utmCoord.x() - xWest);

        // find the vertical SQID offset (100KM increments) from the equator:
        unsigned ySetOffset = 5 * (zone % 2); //(set % 2);
        int sqEquatorOffset = (int)floor(utmCoord.y()/100000.0);
        int absOffset = ySetOffset + sqEquatorOffset + (10 * UTM_ROW_ALPHABET_SIZE);
        if ( _useAL )
            absOffset += 10;
        sqid[1] = UTM_ROW_ALPHABET[absOffset % UTM_ROW_ALPHABET_SIZE];
        y = (unsigned)(utmCoord.y() - (100000.0*(double)sqEquatorOffset));
    }

    if ( (unsigned)_precision > PRECISION_1M )
    {
        x /= (unsigned)_precision;
        y /= (unsigned)_precision;
    }

    out.gzd  = Stringify() << (zone+1) << gzd;
    out.sqid = sqid;
    out.x    = x;
    out.y    = y;

    return true;
}