bool AnnotationNode::makeAbsolute( GeoPoint& mapPoint, osg::Node* patch ) const { // in terrain-clamping mode, force it to HAT=0: if ( _altitude.valid() && ( _altitude->clamping() == AltitudeSymbol::CLAMP_TO_TERRAIN || _altitude->clamping() == AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN) ) { mapPoint.altitudeMode() = ALTMODE_RELATIVE; //If we're clamping to the terrain if (_altitude->clamping() == AltitudeSymbol::CLAMP_TO_TERRAIN) { mapPoint.z() = 0.0; } } // if the point's already absolute and we're not clamping it, nop. if ( mapPoint.altitudeMode() == ALTMODE_ABSOLUTE ) { return true; } // calculate the absolute Z of the map point. if ( getMapNode() ) { // find the terrain height at the map point: double hamsl; if (getMapNode()->getTerrain()->getHeight(patch, mapPoint.getSRS(), mapPoint.x(), mapPoint.y(), &hamsl, 0L)) { // apply any scale/offset in the symbology: if ( _altitude.valid() ) { if ( _altitude->verticalScale().isSet() ) hamsl *= _altitude->verticalScale()->eval(); if ( _altitude->verticalOffset().isSet() ) hamsl += _altitude->verticalOffset()->eval(); } mapPoint.z() += hamsl; } mapPoint.altitudeMode() = ALTMODE_ABSOLUTE; return true; } return false; }
bool ElevationQuery::getElevation(const GeoPoint& point, double& out_elevation, double desiredResolution, double* out_actualResolution) { sync(); if ( point.altitudeMode() == ALTMODE_ABSOLUTE ) { return getElevationImpl( point, out_elevation, desiredResolution, out_actualResolution ); } else { GeoPoint point_abs( point.getSRS(), point.x(), point.y(), 0.0, ALTMODE_ABSOLUTE ); return getElevationImpl( point_abs, out_elevation, desiredResolution, out_actualResolution ); } }
void Dragger::updateTransform(osg::Node* patch) { osg::Matrixd matrix; GeoPoint mapPoint; _mapNode->getMap()->toMapPoint( _position, mapPoint ); //Get the height if (_position.altitudeMode() == ALTMODE_RELATIVE) { double hamsl; if (_mapNode->getTerrain()->getHeight(mapPoint.x(), mapPoint.y(), &hamsl, 0L, patch)) { mapPoint.z() += hamsl; } mapPoint.altitudeMode() = ALTMODE_ABSOLUTE; } mapPoint.createLocalToWorld( matrix ); setMatrix( matrix ); }
float ElevationQuery::getElevation(const GeoPoint& point, double desiredResolution, double* out_actualResolution) { float result = NO_DATA_VALUE; sync(); if ( point.altitudeMode() == ALTMODE_ABSOLUTE ) { getElevationImpl( point, result, desiredResolution, out_actualResolution ); } else { GeoPoint point_abs( point.getSRS(), point.x(), point.y(), 0.0, ALTMODE_ABSOLUTE ); getElevationImpl( point_abs, result, desiredResolution, out_actualResolution ); } return result; }
void LOSCreationDialog::updateLOSNodes(bool updateAll) { if (_p2p.valid() && (updateAll || _ui.typeTabs->tabText(_ui.typeTabs->currentIndex()) == "Point-to-Point")) { if (_ui.depthTestCheckBox->checkState() == Qt::Checked) _p2p->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); else _p2p->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); bool p1Set = false; bool p2Set = false; osg::Node* p1Node = 0L; osg::Node* p2Node = 0L; // get start point or node if (_ui.p1TypeCombo->currentText() == "Point") { _p2p->setStart(GeoPoint( _mapNode->getMapSRS(), _ui.p1LonBox->value(), _ui.p1LatBox->value(), _ui.p1AltBox->value(), _ui.p2pRelativeCheckBox->checkState() == Qt::Checked ? ALTMODE_RELATIVE : ALTMODE_ABSOLUTE) ); //if (_ui.p2pRelativeCheckBox->checkState() == Qt::Checked) // _p2p->setStartAltitudeMode(ALTMODE_RELATIVE); //else // _p2p->setStartAltitudeMode(ALTMODE_ABSOLUTE); p1Set = true; } else if (_ui.p1TypeCombo->currentText() == "Annotation") { GeoPoint p = _p2p->getStart(); p.altitudeMode() = ALTMODE_ABSOLUTE; _p2p->setStart( p ); //_p2p->setStartAltitudeMode(ALTMODE_ABSOLUTE); p1Node = _annotations[_ui.p1NodeCombo->currentIndex()]; p1Set = true; } // get end point or node if (_ui.p2TypeCombo->currentText() == "Point") { _p2p->setEnd(GeoPoint( _mapNode->getMapSRS(), _ui.p2LonBox->value(), _ui.p2LatBox->value(), _ui.p2AltBox->value(), _ui.p2pRelativeCheckBox->checkState() == Qt::Checked ? ALTMODE_RELATIVE : ALTMODE_ABSOLUTE) ); //if (_ui.p2pRelativeCheckBox->checkState() == Qt::Checked) // _p2p->setEndAltitudeMode(ALTMODE_RELATIVE); //else // _p2p->setEndAltitudeMode(ALTMODE_ABSOLUTE); p2Set = true; } else if (_ui.p2TypeCombo->currentText() == "Annotation") { GeoPoint p = _p2p->getEnd(); p.altitudeMode() = ALTMODE_ABSOLUTE; _p2p->setEnd( p ); //_p2p->setEndAltitudeMode(ALTMODE_ABSOLUTE); p2Node = _annotations[_ui.p2NodeCombo->currentIndex()]; p2Set = true; } // set update callback if tethered, else clear it if (p1Node || p2Node) _p2p->setUpdateCallback(new osgEarth::Util::LineOfSightTether(p1Node, p2Node)); else _p2p->setUpdateCallback(0L); } if (_radial.valid() && (updateAll || _ui.typeTabs->tabText(_ui.typeTabs->currentIndex()) == "Radial")) { _radial->setRadius(_ui.radiusSpinBox->value()); _radial->setNumSpokes(_ui.spokesSpinBox->value()); if (_ui.depthTestCheckBox->checkState() == Qt::Checked) _radial->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); else _radial->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); // get center point or node to attach to if (_ui.radTypeCombo->currentText() == "Point") { _radial->setCenter( GeoPoint( _mapNode->getMapSRS(), _ui.radLonBox->value(), _ui.radLatBox->value(), _ui.radAltBox->value(), _ui.radRelativeCheckBox->checkState() == Qt::Checked ? ALTMODE_RELATIVE : ALTMODE_ABSOLUTE) ); //_radial->setCenter(osg::Vec3d(_ui.radLonBox->value(), _ui.radLatBox->value(), _ui.radAltBox->value())); //if (_ui.radRelativeCheckBox->checkState() == Qt::Checked) // _radial->setAltitudeMode(ALTMODE_RELATIVE); //else // _radial->setAltitudeMode(ALTMODE_ABSOLUTE); // clear update callback _radial->setUpdateCallback(0L); } else if (_ui.radTypeCombo->currentText() == "Annotation") { GeoPoint p = _radial->getCenter(); p.altitudeMode() = ALTMODE_ABSOLUTE; _radial->setCenter( p ); //_radial->setAltitudeMode(ALTMODE_ABSOLUTE); _radial->setUpdateCallback(new osgEarth::Util::RadialLineOfSightTether(_annotations[_ui.radNodeCombo->currentIndex()])); } } }
bool Dragger::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { if (ea.getHandled()) return false; osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); if (!view) return false; if (!_mapNode.valid()) return false; if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH) { Picker picker( view, this ); Picker::Hits hits; if ( picker.pick( ea.getX(), ea.getY(), hits ) ) { _dragging = true; //Check for and handle vertical dragging if necessary bool pressedAlt = _modKeyMask && (ea.getModKeyMask() & _modKeyMask) > 0; _elevationDragging = (_defaultMode == Dragger::DRAGMODE_VERTICAL && !pressedAlt) || (_defaultMode == Dragger::DRAGMODE_HORIZONTAL && pressedAlt); if (_elevationDragging) { _pointer.reset(); // set movement range // TODO: values 0.0 and 300000.0 are rather experimental GeoPoint posStart(_position.getSRS(), _position.x(), _position.y(), 0.0, ALTMODE_ABSOLUTE); osg::Vec3d posStartXYZ; posStart.toWorld(posStartXYZ); GeoPoint posEnd(_position.getSRS(), _position.x(), _position.y(), 300000.0, ALTMODE_ABSOLUTE); osg::Vec3d posEndXYZ; posEnd.toWorld(posEndXYZ); _projector->setLine(posStartXYZ, posEndXYZ); // set camera osgUtil::LineSegmentIntersector::Intersections intersections; osg::Node::NodeMask intersectionMask = 0xffffffff; osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); if (view->computeIntersections(ea.getX(),ea.getY(),intersections, intersectionMask)) { for (osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin(); hitr != intersections.end(); ++hitr) { _pointer.addIntersection(hitr->nodePath, hitr->getLocalIntersectPoint()); } bool draggerFound = false; for (osgManipulator::PointerInfo::IntersectionList::iterator piit = _pointer._hitList.begin(); piit != _pointer._hitList.end(); ++piit) { for (osg::NodePath::iterator itr = piit->first.begin(); itr != piit->first.end(); ++itr) { Dragger* dragger = dynamic_cast<Dragger*>(*itr); if (dragger==this) { draggerFound = true; osg::Camera *rootCamera = view->getCamera(); osg::NodePath nodePath = _pointer._hitList.front().first; osg::NodePath::reverse_iterator ritr; for (ritr = nodePath.rbegin(); ritr != nodePath.rend(); ++ritr) { osg::Camera* camera = dynamic_cast<osg::Camera*>(*ritr); if (camera && (camera->getReferenceFrame()!=osg::Transform::RELATIVE_RF || camera->getParents().empty())) { rootCamera = camera; break; } } _pointer.setCamera(rootCamera); _pointer.setMousePosition(ea.getX(), ea.getY()); break; } } if (draggerFound) break; } } } aa.requestRedraw(); return true; } } else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE) { _elevationDragging = false; if ( _dragging ) { _dragging = false; firePositionChanged(); } aa.requestRedraw(); } else if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG) { if (_elevationDragging) { _pointer._hitIter = _pointer._hitList.begin(); _pointer.setMousePosition(ea.getX(), ea.getY()); if (_projector->project(_pointer, _startProjectedPoint)) { //Get the absolute mapPoint that they've drug it to. GeoPoint projectedPos; projectedPos.fromWorld(_position.getSRS(), _startProjectedPoint); // make sure point is not dragged down below // TODO: think of a better solution / HeightAboveTerrain performance issues? if (projectedPos.z() >= _verticalMinimum) { //If the current position is relative, we need to convert the absolute world point to relative. //If the point is absolute then just emit the absolute point. if (_position.altitudeMode() == ALTMODE_RELATIVE) { projectedPos.transformZ(ALTMODE_RELATIVE, getMapNode()->getTerrain()); } setPosition( projectedPos ); aa.requestRedraw(); } } return true; } if (_dragging) { osg::Vec3d world; if ( getMapNode() && getMapNode()->getTerrain()->getWorldCoordsUnderMouse(view, ea.getX(), ea.getY(), world) ) { //Get the absolute mapPoint that they've drug it to. GeoPoint mapPoint; mapPoint.fromWorld( getMapNode()->getMapSRS(), world ); //_mapNode->getMap()->worldPointToMapPoint(world, mapPoint); //If the current position is relative, we need to convert the absolute world point to relative. //If the point is absolute then just emit the absolute point. if (_position.altitudeMode() == ALTMODE_RELATIVE) { mapPoint.alt() = _position.alt(); mapPoint.altitudeMode() = ALTMODE_RELATIVE; } setPosition( mapPoint ); aa.requestRedraw(); return true; } } } else if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE) { Picker picker( view, this ); Picker::Hits hits; if ( picker.pick( ea.getX(), ea.getY(), hits ) ) { setHover( true ); } else { setHover( false ); } aa.requestRedraw(); } return false; }
bool ElevationDragger::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { bool ret = true; if (ea.getHandled()) { ret = false; } else { bool handled = false; if (_elevationMode) { if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH) { ret = osgEarth::Dragger::handle(ea, aa); if (ret) { bool pressedAlt = ((ea.getModKeyMask() & _modKeyMask) > 0); if (pressedAlt) { _pointer.reset(); // set movement range // TODO: values 0.0 and 300000.0 are rather experimental GeoPoint posStart(_position.getSRS(), _position.x(), _position.y(), 0.0, ALTMODE_ABSOLUTE); osg::Vec3d posStartXYZ; posStart.toWorld(posStartXYZ); GeoPoint posEnd(_position.getSRS(), _position.x(), _position.y(), 300000.0, ALTMODE_ABSOLUTE); osg::Vec3d posEndXYZ; posEnd.toWorld(posEndXYZ); _projector->setLine(posStartXYZ, posEndXYZ); // set camera osgUtil::LineSegmentIntersector::Intersections intersections; osg::Node::NodeMask intersectionMask = 0xffffffff; osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); if (view->computeIntersections(ea.getX(),ea.getY(),intersections, intersectionMask)) { for (osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin(); hitr != intersections.end(); ++hitr) { _pointer.addIntersection(hitr->nodePath, hitr->getLocalIntersectPoint()); } for (osg::NodePath::iterator itr = _pointer._hitList.front().first.begin(); itr != _pointer._hitList.front().first.end(); ++itr) { ElevationDragger* dragger = dynamic_cast<ElevationDragger*>(*itr); if (dragger==this) { osg::Camera *rootCamera = view->getCamera(); osg::NodePath nodePath = _pointer._hitList.front().first; osg::NodePath::reverse_iterator ritr; for (ritr = nodePath.rbegin(); ritr != nodePath.rend(); ++ritr) { osg::Camera* camera = dynamic_cast<osg::Camera*>(*ritr); if (camera && (camera->getReferenceFrame()!=osg::Transform::RELATIVE_RF || camera->getParents().empty())) { rootCamera = camera; break; } } _pointer.setCamera(rootCamera); _pointer.setMousePosition(ea.getX(), ea.getY()); } } } _elevationDragging = true; } } handled = true; } else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE) { _elevationDragging = false; } else if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG) { if (_elevationDragging) { _pointer._hitIter = _pointer._hitList.begin(); _pointer.setMousePosition(ea.getX(), ea.getY()); if (_projector->project(_pointer, _startProjectedPoint)) { //Get the absolute mapPoint that they've drug it to. GeoPoint projectedPos; projectedPos.fromWorld(_position.getSRS(), _startProjectedPoint); // make sure point is not dragged down below // TODO: think of a better solution / HeightAboveTerrain performance issues? if (projectedPos.z() > 0) { //If the current position is relative, we need to convert the absolute world point to relative. //If the point is absolute then just emit the absolute point. if (_position.altitudeMode() == ALTMODE_RELATIVE) { projectedPos.alt() = _position.alt(); projectedPos.altitudeMode() = ALTMODE_RELATIVE; } setPosition( projectedPos ); aa.requestRedraw(); } } handled = true; } } } if (!handled) { ret = osgEarth::Dragger::handle(ea, aa); } } return ret; }
bool Dragger::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { if (ea.getHandled()) return false; osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); if (!view) return false; if (!_mapNode.valid()) return false; if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH) { Picker picker( view, this ); Picker::Hits hits; if ( picker.pick( ea.getX(), ea.getY(), hits ) ) { _dragging = true; aa.requestRedraw(); return true; } } else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE) { _dragging = false; aa.requestRedraw(); } else if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG) { if (_dragging) { osg::Vec3d world; if ( _mapNode->getTerrain()->getWorldCoordsUnderMouse(view, ea.getX(), ea.getY(), world) ) { //Get the absolute mapPoint that they've drug it to. GeoPoint mapPoint; mapPoint.fromWorld( _mapNode->getMapSRS(), world ); //_mapNode->getMap()->worldPointToMapPoint(world, mapPoint); //If the current position is relative, we need to convert the absolute world point to relative. //If the point is absolute then just emit the absolute point. if (_position.altitudeMode() == ALTMODE_RELATIVE) { mapPoint.alt() = _position.alt(); mapPoint.altitudeMode() = ALTMODE_RELATIVE; } setPosition( mapPoint ); aa.requestRedraw(); return true; } } } else if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE) { Picker picker( view, this ); Picker::Hits hits; if ( picker.pick( ea.getX(), ea.getY(), hits ) ) { setHover( true ); } else { setHover( false ); } aa.requestRedraw(); } return false; }
bool GeoTransform::setPosition(const GeoPoint& position) { if ( !position.isValid() ) return false; _position = position; // relative Z or reprojection require a terrain: osg::ref_ptr<Terrain> terrain; _terrain.lock(terrain); // relative Z requires a terrain: if (position.altitudeMode() == ALTMODE_RELATIVE && !terrain.valid()) { OE_TEST << LC << "setPosition failed condition 1\n"; return false; } GeoPoint p; // transform into terrain SRS if neccesary: if (terrain.valid() && !terrain->getSRS()->isEquivalentTo(position.getSRS())) p = position.transform(terrain->getSRS()); else p = position; // bail if the transformation failed: if ( !p.isValid() ) { OE_TEST << LC << "setPosition failed condition 2\n"; return false; } // convert to absolute height: if ( !p.makeAbsolute(_terrain.get()) ) { OE_TEST << LC << "setPosition failed condition 3\n"; return false; } // assemble the matrix: osg::Matrixd local2world; p.createLocalToWorld( local2world ); this->setMatrix( local2world ); // install auto-recompute? if (_autoRecompute && _position.altitudeMode() == ALTMODE_RELATIVE && !_autoRecomputeReady) { // by using the adapter, there's no need to remove // the callback then this object destructs. terrain->addTerrainCallback( new TerrainCallbackAdapter<GeoTransform>(this) ); _autoRecomputeReady = true; } return true; }