1/* -*-c++-*- */ 2/* osgEarth - Geospatial SDK for OpenSceneGraph 3 * Copyright 2019 Pelican Mapping 4 * http://osgearth.org 5 * 6 * osgEarth is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/> 18 */ 19 20#ifndef OSGEARTHSYMBOLOGY_EXPRESSION_H 21#define OSGEARTHSYMBOLOGY_EXPRESSION_H 1 22 23#include <osgEarthSymbology/Common> 24#include <osgEarth/Config> 25#include <osgEarth/URI> 26#include <osgEarth/GeoData> 27#include <osgEarth/TileKey> 28 29namespace osgEarth { namespace Symbology 30{ 31 /** 32 * Simple numeric expression evaluator with variables. 33 */ 34 class OSGEARTHSYMBOLOGY_EXPORT NumericExpression 35 { 36 public: 37 typedef std::pair<std::string,unsigned> Variable; 38 typedef std::vector<Variable> Variables; 39 40 public: 41 NumericExpression(); 42 43 NumericExpression( const Config& conf ); 44 45 /** Construct a new expression from the infix string. */ 46 NumericExpression( const std::string& expr ); 47 48 /** Construct a new static expression from a value */ 49 NumericExpression( double staticValue ); 50 51 /** Copy ctor. */ 52 NumericExpression( const NumericExpression& rhs ); 53 54 /** dtor */ 55 virtual ~NumericExpression() { } 56 57 /** Set the result to a literal value. */ 58 void setLiteral( double staticValue ); 59 60 /** Access the expression variables. */ 61 const Variables& variables() const { return _vars; } 62 63 /** Set the value of a variable. */ 64 void set( const Variable& var, double value ); 65 66 /** Evaluate the expression. */ 67 double eval() const; 68 69 /** Gets the expression string. */ 70 const std::string& expr() const { return _src; } 71 72 /** Whether the expression is empty */ 73 bool empty() const { return _src.empty(); } 74 75 public: 76 Config getConfig() const; 77 void mergeConfig( const Config& conf ); 78 79 private: 80 enum Op { OPERAND, VARIABLE, ADD, SUB, MULT, DIV, MOD, MIN, MAX, LPAREN, RPAREN, COMMA }; // in low-high precedence order 81 typedef std::pair<Op,double> Atom; 82 typedef std::vector<Atom> AtomVector; 83 typedef std::stack<Atom> AtomStack; 84 85 std::string _src; 86 AtomVector _rpn; 87 Variables _vars; 88 double _value; 89 bool _dirty; 90 91 void init(); 92 }; 93 94 //-------------------------------------------------------------------- 95 96 /** 97 * Simple string expression evaluator with variables. 98 */ 99 class OSGEARTHSYMBOLOGY_EXPORT StringExpression 100 { 101 public: 102 typedef std::pair<std::string,unsigned> Variable; 103 typedef std::vector<Variable> Variables; 104 105 public: 106 StringExpression(); 107 108 StringExpression( const Config& conf ); 109 110 /** Construct a new expression from the infix string. */ 111 StringExpression( const std::string& expr ); 112 113 /** Construct an expression from the infix string and a URI context. */ 114 StringExpression( const std::string& expr, const URIContext& uriContext ); 115 116 /** Copy ctor. */ 117 StringExpression( const StringExpression& rhs ); 118 119 /** dtor */ 120 virtual ~StringExpression() { } 121 122 /** Set the infix expr. */ 123 void setInfix( const std::string& infix ); 124 125 /** Set the infix expr to a literal string */ 126 void setLiteral( const std::string& value ); 127 128 /** Access the expression variables. */ 129 const Variables& variables() const { return _vars; } 130 131 /** Set the value of a variable. */ 132 void set( const Variable& var, const std::string& value ); 133 134 /** Set the value of a names variable if it exists */ 135 void set( const std::string& varName, const std::string& value ); 136 137 /** Evaluate the expression. */ 138 const std::string& eval() const; 139 140 /** Evaluate the expression as a URI. 141 TODO: it would be better to have a whole new subclass URIExpression */ 142 URI evalURI() const; 143 144 /** Gets the expression string. */ 145 const std::string& expr() const { return _src; } 146 147 /** Whether the expression is empty */ 148 bool empty() const { return _src.empty(); } 149 150 void setURIContext( const URIContext& uriContext ) { _uriContext = uriContext; } 151 const URIContext& uriContext() const { return _uriContext; } 152 153 public: 154 Config getConfig() const; 155 void mergeConfig( const Config& conf ); 156 157 private: 158 enum Op { OPERAND, VARIABLE }; // in low-high precedence order 159 typedef std::pair<Op,std::string> Atom; 160 typedef std::vector<Atom> AtomVector; 161 162 std::string _src; 163 AtomVector _infix; 164 Variables _vars; 165 std::string _value; 166 bool _dirty; 167 URIContext _uriContext; 168 169 void init(); 170 }; 171 172 173} } // namespace osgEarth::Symbology 174 175OSGEARTH_SPECIALIZE_CONFIG(osgEarth::Symbology::NumericExpression); 176OSGEARTH_SPECIALIZE_CONFIG(osgEarth::Symbology::StringExpression); 177 178#endif // OSGEARTHSYMBOLOGY_EXPRESSION_H 179