mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-30 21:30:05 +00:00 
			
		
		
		
	Initial placefile parsing
This commit is contained in:
		
							parent
							
								
									7c863793ea
								
							
						
					
					
						commit
						88475f5b0e
					
				
					 6 changed files with 569 additions and 0 deletions
				
			
		
							
								
								
									
										21
									
								
								wxdata/include/scwx/gr/color.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								wxdata/include/scwx/gr/color.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <scwx/gr/gr_types.hpp> | ||||||
|  | 
 | ||||||
|  | #include <string> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <boost/gil/typedefs.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace gr | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | boost::gil::rgba8_pixel_t ParseColor(const std::vector<std::string>& tokenList, | ||||||
|  |                                      std::size_t                     startIndex, | ||||||
|  |                                      ColorMode                       colorMode, | ||||||
|  |                                      bool hasAlpha = true); | ||||||
|  | 
 | ||||||
|  | } // namespace gr
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										15
									
								
								wxdata/include/scwx/gr/gr_types.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								wxdata/include/scwx/gr/gr_types.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace gr | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | enum class ColorMode | ||||||
|  | { | ||||||
|  |    RGBA, | ||||||
|  |    HSLuv | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace gr
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										47
									
								
								wxdata/include/scwx/gr/placefile.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								wxdata/include/scwx/gr/placefile.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <istream> | ||||||
|  | #include <memory> | ||||||
|  | #include <string> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <boost/gil/typedefs.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace gr | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Place File | ||||||
|  |  * | ||||||
|  |  * Implementation based on: | ||||||
|  |  * Place File Specification | ||||||
|  |  * Mike Gibson | ||||||
|  |  * Gibson Ridge Software, LLC.  Used with permission. | ||||||
|  |  * http://www.grlevelx.com/manuals/gis/files_places.htm
 | ||||||
|  |  */ | ||||||
|  | class Placefile | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit Placefile(); | ||||||
|  |    ~Placefile(); | ||||||
|  | 
 | ||||||
|  |    Placefile(const Placefile&)            = delete; | ||||||
|  |    Placefile& operator=(const Placefile&) = delete; | ||||||
|  | 
 | ||||||
|  |    Placefile(Placefile&&) noexcept; | ||||||
|  |    Placefile& operator=(Placefile&&) noexcept; | ||||||
|  | 
 | ||||||
|  |    bool                      IsValid() const; | ||||||
|  | 
 | ||||||
|  |    static std::shared_ptr<Placefile> Load(const std::string& filename); | ||||||
|  |    static std::shared_ptr<Placefile> Load(std::istream& is); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace common
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										86
									
								
								wxdata/source/scwx/gr/color.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								wxdata/source/scwx/gr/color.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | ||||||
|  | #include <scwx/gr/color.hpp> | ||||||
|  | 
 | ||||||
|  | #include <limits> | ||||||
|  | 
 | ||||||
|  | #include <hsluv.h> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace gr | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
|  | T RoundChannel(double value); | ||||||
|  | template<typename T> | ||||||
|  | T StringToDecimal(const std::string& str); | ||||||
|  | 
 | ||||||
|  | boost::gil::rgba8_pixel_t ParseColor(const std::vector<std::string>& tokenList, | ||||||
|  |                                      std::size_t                     startIndex, | ||||||
|  |                                      ColorMode                       colorMode, | ||||||
|  |                                      bool                            hasAlpha) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |    std::uint8_t r {}; | ||||||
|  |    std::uint8_t g {}; | ||||||
|  |    std::uint8_t b {}; | ||||||
|  |    std::uint8_t a = 255; | ||||||
|  | 
 | ||||||
|  |    if (colorMode == ColorMode::RGBA) | ||||||
|  |    { | ||||||
|  |       if (tokenList.size() >= startIndex + 3) | ||||||
|  |       { | ||||||
|  |          r = StringToDecimal<std::uint8_t>(tokenList[startIndex + 0]); | ||||||
|  |          g = StringToDecimal<std::uint8_t>(tokenList[startIndex + 1]); | ||||||
|  |          b = StringToDecimal<std::uint8_t>(tokenList[startIndex + 2]); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (hasAlpha && tokenList.size() >= startIndex + 4) | ||||||
|  |       { | ||||||
|  |          a = StringToDecimal<std::uint8_t>(tokenList[startIndex + 3]); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    else // if (colorMode == ColorMode::HSLuv)
 | ||||||
|  |    { | ||||||
|  |       double h {}; | ||||||
|  |       double s {}; | ||||||
|  |       double l {}; | ||||||
|  | 
 | ||||||
|  |       if (tokenList.size() >= startIndex + 3) | ||||||
|  |       { | ||||||
|  |          h = std::stod(tokenList[startIndex + 0]); | ||||||
|  |          s = std::stod(tokenList[startIndex + 1]); | ||||||
|  |          l = std::stod(tokenList[startIndex + 2]); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       double dr; | ||||||
|  |       double dg; | ||||||
|  |       double db; | ||||||
|  | 
 | ||||||
|  |       hsluv2rgb(h, s, l, &dr, &dg, &db); | ||||||
|  | 
 | ||||||
|  |       r = RoundChannel<std::uint8_t>(dr * 255.0); | ||||||
|  |       g = RoundChannel<std::uint8_t>(dg * 255.0); | ||||||
|  |       b = RoundChannel<std::uint8_t>(db * 255.0); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return boost::gil::rgba8_pixel_t {r, g, b, a}; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
|  | T RoundChannel(double value) | ||||||
|  | { | ||||||
|  |    return static_cast<T>(std::clamp<int>(std::lround(value), | ||||||
|  |                                          std::numeric_limits<T>::min(), | ||||||
|  |                                          std::numeric_limits<T>::max())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
|  | T StringToDecimal(const std::string& str) | ||||||
|  | { | ||||||
|  |    return static_cast<T>(std::clamp<int>(std::stoi(str), | ||||||
|  |                                          std::numeric_limits<T>::min(), | ||||||
|  |                                          std::numeric_limits<T>::max())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace gr
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										391
									
								
								wxdata/source/scwx/gr/placefile.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										391
									
								
								wxdata/source/scwx/gr/placefile.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,391 @@ | ||||||
|  | #include <scwx/gr/placefile.hpp> | ||||||
|  | #include <scwx/gr/color.hpp> | ||||||
|  | #include <scwx/util/logger.hpp> | ||||||
|  | #include <scwx/util/streams.hpp> | ||||||
|  | 
 | ||||||
|  | #include <fstream> | ||||||
|  | #include <regex> | ||||||
|  | #include <sstream> | ||||||
|  | #include <unordered_map> | ||||||
|  | 
 | ||||||
|  | #include <boost/algorithm/string.hpp> | ||||||
|  | #include <boost/tokenizer.hpp> | ||||||
|  | #include <boost/units/base_units/metric/nautical_mile.hpp> | ||||||
|  | #include <boost/units/quantity.hpp> | ||||||
|  | #include <boost/units/systems/si/length.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace gr | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::string logPrefix_ {"scwx::gr::placefile"}; | ||||||
|  | static const auto        logger_ = util::Logger::Create(logPrefix_); | ||||||
|  | 
 | ||||||
|  | enum class DrawingStatement | ||||||
|  | { | ||||||
|  |    Standard, | ||||||
|  |    Line, | ||||||
|  |    Triangles, | ||||||
|  |    Image, | ||||||
|  |    Polygon | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class Placefile::Impl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit Impl() = default; | ||||||
|  |    ~Impl()         = default; | ||||||
|  | 
 | ||||||
|  |    struct Object | ||||||
|  |    { | ||||||
|  |       double x_ {}; | ||||||
|  |       double y_ {}; | ||||||
|  |    }; | ||||||
|  | 
 | ||||||
|  |    struct DrawItem | ||||||
|  |    { | ||||||
|  |    }; | ||||||
|  | 
 | ||||||
|  |    struct PlaceDrawItem : DrawItem | ||||||
|  |    { | ||||||
|  |       boost::units::quantity<boost::units::si::length> threshold_ {}; | ||||||
|  |       boost::gil::rgba8_pixel_t                        color_ {}; | ||||||
|  |       double                                           latitude_ {}; | ||||||
|  |       double                                           longitude_ {}; | ||||||
|  |       double                                           x_ {}; | ||||||
|  |       double                                           y_ {}; | ||||||
|  |       std::string                                      text_ {}; | ||||||
|  |    }; | ||||||
|  | 
 | ||||||
|  |    void ParseLocation(const std::string& latitudeToken, | ||||||
|  |                       const std::string& longitudeToken, | ||||||
|  |                       double&            latitude, | ||||||
|  |                       double&            longitude, | ||||||
|  |                       double&            x, | ||||||
|  |                       double&            y); | ||||||
|  |    void ProcessLine(const std::string&              line, | ||||||
|  |                     const std::vector<std::string>& tokenList); | ||||||
|  | 
 | ||||||
|  |    std::chrono::seconds refresh_ {-1}; | ||||||
|  | 
 | ||||||
|  |    // Parsing state
 | ||||||
|  |    boost::units::quantity<boost::units::si::length> threshold_ { | ||||||
|  |       999.0 * boost::units::metric::nautical_mile_base_unit::unit_type()}; | ||||||
|  |    boost::gil::rgba8_pixel_t color_ {255, 255, 255, 255}; | ||||||
|  |    ColorMode                 colorMode_ {ColorMode::RGBA}; | ||||||
|  |    std::vector<Object>       objectStack_ {}; | ||||||
|  |    DrawingStatement          currentStatement_ {DrawingStatement::Standard}; | ||||||
|  | 
 | ||||||
|  |    // References
 | ||||||
|  |    std::unordered_map<std::size_t, bool> iconFiles_ {}; | ||||||
|  |    std::unordered_map<std::size_t, bool> fonts_ {}; | ||||||
|  | 
 | ||||||
|  |    std::vector<std::shared_ptr<DrawItem>> drawItems_ {}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | Placefile::Placefile() : p(std::make_unique<Impl>()) {} | ||||||
|  | Placefile::~Placefile() = default; | ||||||
|  | 
 | ||||||
|  | Placefile::Placefile(Placefile&&) noexcept            = default; | ||||||
|  | Placefile& Placefile::operator=(Placefile&&) noexcept = default; | ||||||
|  | 
 | ||||||
|  | bool Placefile::IsValid() const | ||||||
|  | { | ||||||
|  |    return p->drawItems_.size() > 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::shared_ptr<Placefile> Placefile::Load(const std::string& filename) | ||||||
|  | { | ||||||
|  |    logger_->debug("Loading placefile: {}", filename); | ||||||
|  |    std::ifstream f(filename, std::ios_base::in); | ||||||
|  |    return Load(f); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::shared_ptr<Placefile> Placefile::Load(std::istream& is) | ||||||
|  | { | ||||||
|  |    std::shared_ptr<Placefile> placefile = std::make_shared<Placefile>(); | ||||||
|  | 
 | ||||||
|  |    std::string line; | ||||||
|  |    while (scwx::util::getline(is, line)) | ||||||
|  |    { | ||||||
|  |       // Find position of comment (;)
 | ||||||
|  |       std::size_t lineEnd = line.find(';'); | ||||||
|  |       if (lineEnd == std::string::npos) | ||||||
|  |       { | ||||||
|  |          // Remove comment
 | ||||||
|  |          line.erase(lineEnd); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Remove extra spacing from line
 | ||||||
|  |       boost::trim(line); | ||||||
|  | 
 | ||||||
|  |       boost::char_separator<char> delimiter(", "); | ||||||
|  |       boost::tokenizer            tokens(line, delimiter); | ||||||
|  |       std::vector<std::string>    tokenList; | ||||||
|  | 
 | ||||||
|  |       for (auto& token : tokens) | ||||||
|  |       { | ||||||
|  |          tokenList.push_back(token); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (tokenList.size() >= 1) | ||||||
|  |       { | ||||||
|  |          try | ||||||
|  |          { | ||||||
|  |             switch (placefile->p->currentStatement_) | ||||||
|  |             { | ||||||
|  |             case DrawingStatement::Standard: | ||||||
|  |                placefile->p->ProcessLine(line, tokenList); | ||||||
|  |                break; | ||||||
|  | 
 | ||||||
|  |             case DrawingStatement::Line: | ||||||
|  |             case DrawingStatement::Triangles: | ||||||
|  |             case DrawingStatement::Image: | ||||||
|  |             case DrawingStatement::Polygon: | ||||||
|  |                if (boost::iequals(tokenList[0], "End:")) | ||||||
|  |                { | ||||||
|  |                   placefile->p->currentStatement_ = DrawingStatement::Standard; | ||||||
|  |                } | ||||||
|  |                break; | ||||||
|  |             } | ||||||
|  |          } | ||||||
|  |          catch (const std::exception&) | ||||||
|  |          { | ||||||
|  |             logger_->warn("Could not parse line: {}", line); | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return placefile; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Placefile::Impl::ProcessLine(const std::string&              line, | ||||||
|  |                                   const std::vector<std::string>& tokenList) | ||||||
|  | { | ||||||
|  |    currentStatement_ = DrawingStatement::Standard; | ||||||
|  | 
 | ||||||
|  |    if (boost::iequals(tokenList[0], "Threshold:")) | ||||||
|  |    { | ||||||
|  |       // Threshold: nautical_miles
 | ||||||
|  |       if (tokenList.size() >= 2) | ||||||
|  |       { | ||||||
|  |          threshold_ = | ||||||
|  |             static_cast<boost::units::quantity<boost::units::si::length>>( | ||||||
|  |                std::stod(tokenList[1]) * | ||||||
|  |                boost::units::metric::nautical_mile_base_unit::unit_type()); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "HSLuv:")) | ||||||
|  |    { | ||||||
|  |       // HSLuv: value
 | ||||||
|  |       if (tokenList.size() >= 2) | ||||||
|  |       { | ||||||
|  |          if (boost::iequals(tokenList[1], "true")) | ||||||
|  |          { | ||||||
|  |             colorMode_ = ColorMode::HSLuv; | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |          { | ||||||
|  |             colorMode_ = ColorMode::RGBA; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "Color:")) | ||||||
|  |    { | ||||||
|  |       // Color: red green blue
 | ||||||
|  |       if (tokenList.size() >= 2) | ||||||
|  |       { | ||||||
|  |          color_ = ParseColor(tokenList, 1, colorMode_); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "Refresh:")) | ||||||
|  |    { | ||||||
|  |       // Refresh: minutes
 | ||||||
|  |       if (tokenList.size() >= 2) | ||||||
|  |       { | ||||||
|  |          refresh_ = std::chrono::minutes {std::stoi(tokenList[1])}; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "RefreshSeconds:")) | ||||||
|  |    { | ||||||
|  |       // RefreshSeconds: seconds
 | ||||||
|  |       if (tokenList.size() >= 2) | ||||||
|  |       { | ||||||
|  |          refresh_ = std::chrono::seconds {std::stoi(tokenList[1])}; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "Place:")) | ||||||
|  |    { | ||||||
|  |       // Place: latitude, longitude, string with spaces
 | ||||||
|  |       std::regex  re {"Place:\\s*([+\\-0-9\\.]+),\\s*([+\\-0-9\\.]+),\\s*(.+)"}; | ||||||
|  |       std::smatch match; | ||||||
|  |       std::regex_match(line, match, re); | ||||||
|  | 
 | ||||||
|  |       if (match.size() >= 4) | ||||||
|  |       { | ||||||
|  |          std::shared_ptr<PlaceDrawItem> di = std::make_shared<PlaceDrawItem>(); | ||||||
|  | 
 | ||||||
|  |          di->threshold_ = threshold_; | ||||||
|  |          di->color_     = color_; | ||||||
|  | 
 | ||||||
|  |          ParseLocation(match[1].str(), | ||||||
|  |                        match[2].str(), | ||||||
|  |                        di->latitude_, | ||||||
|  |                        di->longitude_, | ||||||
|  |                        di->x_, | ||||||
|  |                        di->y_); | ||||||
|  | 
 | ||||||
|  |          di->text_ = match[3].str(); | ||||||
|  | 
 | ||||||
|  |          drawItems_.emplace_back(std::move(di)); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          logger_->warn("Place statement malformed: {}", line); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "IconFile:")) | ||||||
|  |    { | ||||||
|  |       // IconFile: fileNumber, iconWidth, iconHeight, hotX, hotY, fileName
 | ||||||
|  | 
 | ||||||
|  |       // TODO
 | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "Icon:")) | ||||||
|  |    { | ||||||
|  |       // Icon: lat, lon, angle, fileNumber, iconNumber, hoverText
 | ||||||
|  | 
 | ||||||
|  |       // TODO
 | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "Font:")) | ||||||
|  |    { | ||||||
|  |       // Font: fontNumber, pixels, flags, "face"
 | ||||||
|  | 
 | ||||||
|  |       // TODO
 | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "Text:")) | ||||||
|  |    { | ||||||
|  |       // Text: lat, lon, fontNumber, "string", "hover"
 | ||||||
|  | 
 | ||||||
|  |       // TODO
 | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "Object:")) | ||||||
|  |    { | ||||||
|  |       // Object: lat, lon
 | ||||||
|  |       //    ...
 | ||||||
|  |       // End:
 | ||||||
|  |       std::regex  re {"Object:\\s*([+\\-0-9\\.]+),\\s*([+\\-0-9\\.]+)"}; | ||||||
|  |       std::smatch match; | ||||||
|  |       std::regex_match(line, match, re); | ||||||
|  | 
 | ||||||
|  |       double latitude {}; | ||||||
|  |       double longitude {}; | ||||||
|  | 
 | ||||||
|  |       if (match.size() >= 3) | ||||||
|  |       { | ||||||
|  |          latitude  = std::stod(match[1].str()); | ||||||
|  |          longitude = std::stod(match[2].str()); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          logger_->warn("Object statement malformed: {}", line); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       objectStack_.emplace_back(Object {latitude, longitude}); | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "End:")) | ||||||
|  |    { | ||||||
|  |       // Object End
 | ||||||
|  |       if (!objectStack_.empty()) | ||||||
|  |       { | ||||||
|  |          objectStack_.pop_back(); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          logger_->warn("End found without Object"); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "Line:")) | ||||||
|  |    { | ||||||
|  |       // Line: width, flags [, hover_text]
 | ||||||
|  |       //    lat, lon
 | ||||||
|  |       //    ...
 | ||||||
|  |       // End:
 | ||||||
|  |       currentStatement_ = DrawingStatement::Line; | ||||||
|  | 
 | ||||||
|  |       // TODO
 | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "Triangles:")) | ||||||
|  |    { | ||||||
|  |       // Triangles:
 | ||||||
|  |       //    lat, lon [, r, g, b [,a]]
 | ||||||
|  |       //    ...
 | ||||||
|  |       // End:
 | ||||||
|  |       currentStatement_ = DrawingStatement::Triangles; | ||||||
|  | 
 | ||||||
|  |       // TODO
 | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "Image:")) | ||||||
|  |    { | ||||||
|  |       // Image: image_file
 | ||||||
|  |       //    lat, lon, Tu [, Tv ]
 | ||||||
|  |       //    ...
 | ||||||
|  |       // End:
 | ||||||
|  |       currentStatement_ = DrawingStatement::Image; | ||||||
|  | 
 | ||||||
|  |       // TODO
 | ||||||
|  |    } | ||||||
|  |    else if (boost::iequals(tokenList[0], "Polygon:")) | ||||||
|  |    { | ||||||
|  |       // Polygon:
 | ||||||
|  |       //    lat1, lon1 [, r, g, b [,a]] ; start of the first contour
 | ||||||
|  |       //    ...
 | ||||||
|  |       //    lat1, lon1                  ; repeating the first point closes the
 | ||||||
|  |       //                                ; contour
 | ||||||
|  |       //
 | ||||||
|  |       //    lat2, lon2                  ; next point starts a new contour
 | ||||||
|  |       //    ...
 | ||||||
|  |       //    lat2, lon2                  ; and repeating it ends the contour
 | ||||||
|  |       // End:
 | ||||||
|  |       currentStatement_ = DrawingStatement::Polygon; | ||||||
|  | 
 | ||||||
|  |       // TODO
 | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Placefile::Impl::ParseLocation(const std::string& latitudeToken, | ||||||
|  |                                     const std::string& longitudeToken, | ||||||
|  |                                     double&            latitude, | ||||||
|  |                                     double&            longitude, | ||||||
|  |                                     double&            x, | ||||||
|  |                                     double&            y) | ||||||
|  | { | ||||||
|  |    if (objectStack_.empty()) | ||||||
|  |    { | ||||||
|  |       // If an Object statement is not currently open, parse latitude and
 | ||||||
|  |       // longitude tokens as-is
 | ||||||
|  |       latitude  = std::stod(latitudeToken); | ||||||
|  |       longitude = std::stod(longitudeToken); | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       // If an Object statement is open, the latitude and longitude are from the
 | ||||||
|  |       // outermost Object
 | ||||||
|  |       latitude  = objectStack_[0].x_; | ||||||
|  |       longitude = objectStack_[0].y_; | ||||||
|  | 
 | ||||||
|  |       // The latitude and longitude tokens are interpreted as x, y offsets
 | ||||||
|  |       x = std::stod(latitudeToken); | ||||||
|  |       y = std::stod(longitudeToken); | ||||||
|  | 
 | ||||||
|  |       // If there are inner Object statements open, treat these as x, y offsets
 | ||||||
|  |       for (std::size_t i = 1; i < objectStack_.size(); i++) | ||||||
|  |       { | ||||||
|  |          x += objectStack_[i].x_; | ||||||
|  |          y += objectStack_[i].y_; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace gr
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | @ -45,6 +45,11 @@ set(SRC_COMMON source/scwx/common/characters.cpp | ||||||
|                source/scwx/common/products.cpp |                source/scwx/common/products.cpp | ||||||
|                source/scwx/common/sites.cpp |                source/scwx/common/sites.cpp | ||||||
|                source/scwx/common/vcp.cpp) |                source/scwx/common/vcp.cpp) | ||||||
|  | set(HDR_GR include/scwx/gr/color.hpp | ||||||
|  |            include/scwx/gr/gr_types.hpp | ||||||
|  |            include/scwx/gr/placefile.hpp) | ||||||
|  | set(SRC_GR source/scwx/gr/color.cpp | ||||||
|  |            source/scwx/gr/placefile.cpp) | ||||||
| set(HDR_NETWORK include/scwx/network/dir_list.hpp) | set(HDR_NETWORK include/scwx/network/dir_list.hpp) | ||||||
| set(SRC_NETWORK source/scwx/network/dir_list.cpp) | set(SRC_NETWORK source/scwx/network/dir_list.cpp) | ||||||
| set(HDR_PROVIDER include/scwx/provider/aws_level2_data_provider.hpp | set(HDR_PROVIDER include/scwx/provider/aws_level2_data_provider.hpp | ||||||
|  | @ -195,6 +200,8 @@ add_library(wxdata OBJECT ${HDR_AWIPS} | ||||||
|                           ${SRC_AWIPS} |                           ${SRC_AWIPS} | ||||||
|                           ${HDR_COMMON} |                           ${HDR_COMMON} | ||||||
|                           ${SRC_COMMON} |                           ${SRC_COMMON} | ||||||
|  |                           ${HDR_GR} | ||||||
|  |                           ${SRC_GR} | ||||||
|                           ${HDR_NETWORK} |                           ${HDR_NETWORK} | ||||||
|                           ${SRC_NETWORK} |                           ${SRC_NETWORK} | ||||||
|                           ${HDR_PROVIDER} |                           ${HDR_PROVIDER} | ||||||
|  | @ -213,6 +220,8 @@ source_group("Header Files\\awips"       FILES ${HDR_AWIPS}) | ||||||
| source_group("Source Files\\awips"       FILES ${SRC_AWIPS}) | source_group("Source Files\\awips"       FILES ${SRC_AWIPS}) | ||||||
| source_group("Header Files\\common"      FILES ${HDR_COMMON}) | source_group("Header Files\\common"      FILES ${HDR_COMMON}) | ||||||
| source_group("Source Files\\common"      FILES ${SRC_COMMON}) | source_group("Source Files\\common"      FILES ${SRC_COMMON}) | ||||||
|  | source_group("Header Files\\gr"          FILES ${HDR_GR}) | ||||||
|  | source_group("Source Files\\gr"          FILES ${SRC_GR}) | ||||||
| source_group("Header Files\\network"     FILES ${HDR_NETWORK}) | source_group("Header Files\\network"     FILES ${HDR_NETWORK}) | ||||||
| source_group("Source Files\\network"     FILES ${SRC_NETWORK}) | source_group("Source Files\\network"     FILES ${SRC_NETWORK}) | ||||||
| source_group("Header Files\\provider"    FILES ${HDR_PROVIDER}) | source_group("Header Files\\provider"    FILES ${HDR_PROVIDER}) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat