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