/* -*-c++-*- */ /* osgEarth - Geospatial SDK for OpenSceneGraph * Copyright 2020 Pelican Mapping * http://osgearth.org * * osgEarth is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ #pragma once #include #include #include #include #include #include namespace osgEarth { /** * Defines for a labeling field associated with a TrackNode. A TrackNode * can have zero or more "fields", each being a text label rendered * along with the node's icon. */ struct /*no-export*/ TrackNodeField { /** * Constructs a new field definition. * @param symbol Text symbol describing the field's appearance and placement * @param dynamic Whether the text label will be dynamic; i.e. whether the user * intends to update it at runtime. Setting this to "false" for a * static label yields better performance in a multithreaded app. */ TrackNodeField( const TextSymbol* symbol, bool dynamic =true ) : _symbol(symbol), _dynamic(dynamic) { } /** other constructors (internal) */ TrackNodeField() : _dynamic(true) { } TrackNodeField( const TrackNodeField& rhs ) : _symbol(rhs._symbol.get()), _dynamic(rhs._dynamic) { } osg::ref_ptr _symbol; bool _dynamic; }; /** * Schema that maps field names to field definitions. */ typedef std::map TrackNodeFieldSchema; /** * TrackNode is a movable, single-point entity represented by an icon, * optional placeable text labels, and optional localized geometry. * * NOTE. TrackNode does not automatically support terrain clamping. This is * because its intention is for use as a trackable entity marker, and * presumably the entity itself will be responsible for its own absolute * positioning (and clamping, if applicable). */ class OSGEARTH_EXPORT TrackNode : public GeoPositionNode { public: META_AnnotationNode(osgEarth, TrackNode); /** * Constructs a new track node * @param mapNode Map node under which this track will live * @param position Initial position * @param image Icon image to use * @param fieldSchema Schema for track label fields */ TrackNode( const GeoPoint& position, osg::Image* image, const TrackNodeFieldSchema& fieldSchema ); /** * Constructs a new track node * @param mapNode Map node under which this track will live * @param position Initial position * @param style Style containing an IconSymbol for the image * @param fieldSchema Schema for track label fields */ TrackNode( const GeoPoint& position, const Style& style, const TrackNodeFieldSchema& fieldSchema ); /** * Sets the value of one of the field labels. * @param name Field name as identified in the field schema. * @param value Value to which to set the field label. */ void setFieldValue( const std::string& name, const std::string& value ) { setFieldValue(name, osgText::String(value)); } void setFieldValue( const std::string& name, const osgText::String& value ); /** * Adds an arbitrary drawable to this track node. Useful for adding * user-defined graphics. * @param name Name of the drawable (for later retrieval). The namespace * should not conflict with that of the field schema. * @param drawable Drawable to add. */ void addDrawable( const std::string& name, osg::Drawable* drawable ); /** * Gets a drawable (as previously added with addDrawable). * Note: Make sure that if you are modifying a drawable, mark it with a * DYNAMIC data variance so it will be thread-safe. */ osg::Drawable* getDrawable( const std::string& name ) const; void setIconRotation(const Angle& angle); const Angle& getIconRotation() const { return _iconAngle; } public: // AnnotationNode virtual void setPriority(float value); protected: // AnnotationNode override virtual bool supportsRenderBinDetails() const { return false; } protected: virtual ~TrackNode() { } private: // required by META_Node, but this object is not cloneable TrackNode() { } TrackNode(const TrackNode& rhs, const osg::CopyOp& op =osg::CopyOp::DEEP_COPY_ALL) { } void updateLayoutData(); void construct(); static osg::observer_ptr s_geodeStateSet; static osg::observer_ptr s_imageStateSet; osg::ref_ptr _imageStateSet; Angle _iconAngle; osg::Drawable* _iconDrawable = nullptr; Style _style; class osg::Group* _geode; TrackNodeFieldSchema _fieldSchema; using NamedDrawables = std::unordered_map; NamedDrawables _namedDrawables; void compile(); }; }