mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 02:20:04 +00:00 
			
		
		
		
	Support loadable radar sites
This commit is contained in:
		
							parent
							
								
									56cda08b0d
								
							
						
					
					
						commit
						9c2f86b00a
					
				
					 8 changed files with 510 additions and 3 deletions
				
			
		
							
								
								
									
										157
									
								
								scwx-qt/source/scwx/qt/config/radar_site.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								scwx-qt/source/scwx/qt/config/radar_site.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,157 @@ | |||
| #include <scwx/qt/config/radar_site.hpp> | ||||
| #include <scwx/qt/util/json.hpp> | ||||
| 
 | ||||
| #include <unordered_map> | ||||
| 
 | ||||
| #include <boost/log/trivial.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace config | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "[scwx::qt::settings::radar_site] "; | ||||
| 
 | ||||
| static std::unordered_map<std::string, std::shared_ptr<RadarSite>> | ||||
|    radarSiteMap_; | ||||
| 
 | ||||
| static bool ValidateJsonEntry(const boost::json::object& o); | ||||
| 
 | ||||
| class RadarSiteImpl | ||||
| { | ||||
| public: | ||||
|    explicit RadarSiteImpl() : | ||||
|        type_ {}, | ||||
|        id_ {}, | ||||
|        latitude_ {0.0}, | ||||
|        longitude_ {0.0}, | ||||
|        country_ {}, | ||||
|        state_ {}, | ||||
|        place_ {} | ||||
|    { | ||||
|    } | ||||
| 
 | ||||
|    ~RadarSiteImpl() {} | ||||
| 
 | ||||
|    std::string type_; | ||||
|    std::string id_; | ||||
|    double      latitude_; | ||||
|    double      longitude_; | ||||
|    std::string country_; | ||||
|    std::string state_; | ||||
|    std::string place_; | ||||
| }; | ||||
| 
 | ||||
| RadarSite::RadarSite() : p(std::make_unique<RadarSiteImpl>()) {} | ||||
| RadarSite::~RadarSite() = default; | ||||
| 
 | ||||
| RadarSite::RadarSite(RadarSite&&) noexcept = default; | ||||
| RadarSite& RadarSite::operator=(RadarSite&&) noexcept = default; | ||||
| 
 | ||||
| std::string RadarSite::type() const | ||||
| { | ||||
|    return p->type_; | ||||
| } | ||||
| 
 | ||||
| std::string RadarSite::id() const | ||||
| { | ||||
|    return p->id_; | ||||
| } | ||||
| 
 | ||||
| double RadarSite::latitude() const | ||||
| { | ||||
|    return p->latitude_; | ||||
| } | ||||
| 
 | ||||
| double RadarSite::longitude() const | ||||
| { | ||||
|    return p->longitude_; | ||||
| } | ||||
| 
 | ||||
| std::string RadarSite::country() const | ||||
| { | ||||
|    return p->country_; | ||||
| } | ||||
| 
 | ||||
| std::string RadarSite::state() const | ||||
| { | ||||
|    return p->state_; | ||||
| } | ||||
| 
 | ||||
| std::string RadarSite::place() const | ||||
| { | ||||
|    return p->place_; | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<RadarSite> RadarSite::Get(const std::string& id) | ||||
| { | ||||
|    std::shared_ptr<RadarSite> radarSite = nullptr; | ||||
| 
 | ||||
|    if (radarSiteMap_.contains(id)) | ||||
|    { | ||||
|       radarSite = radarSiteMap_.at(id); | ||||
|    } | ||||
| 
 | ||||
|    return radarSite; | ||||
| } | ||||
| 
 | ||||
| size_t RadarSite::ReadConfig(const std::string& path) | ||||
| { | ||||
|    bool   dataValid  = true; | ||||
|    size_t sitesAdded = 0; | ||||
| 
 | ||||
|    boost::json::value j = util::json::ReadJsonFile(path); | ||||
| 
 | ||||
|    dataValid = j.is_array(); | ||||
| 
 | ||||
|    if (dataValid) | ||||
|    { | ||||
|       for (auto& v : j.as_array()) | ||||
|       { | ||||
|          auto& o = v.as_object(); | ||||
| 
 | ||||
|          if (!ValidateJsonEntry(o)) | ||||
|          { | ||||
|             BOOST_LOG_TRIVIAL(info) << logPrefix_ << "Incorrect format: " << v; | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             std::shared_ptr<RadarSite> site = std::make_shared<RadarSite>(); | ||||
| 
 | ||||
|             site->p->type_ = boost::json::value_to<std::string>(o.at("type")); | ||||
|             site->p->id_   = boost::json::value_to<std::string>(o.at("id")); | ||||
|             site->p->latitude_  = boost::json::value_to<double>(o.at("lat")); | ||||
|             site->p->longitude_ = boost::json::value_to<double>(o.at("lon")); | ||||
|             site->p->country_ = | ||||
|                boost::json::value_to<std::string>(o.at("country")); | ||||
|             site->p->state_ = boost::json::value_to<std::string>(o.at("state")); | ||||
|             site->p->place_ = boost::json::value_to<std::string>(o.at("place")); | ||||
| 
 | ||||
|             if (!radarSiteMap_.contains(site->p->id_)) | ||||
|             { | ||||
|                radarSiteMap_[site->p->id_] = site; | ||||
|                ++sitesAdded; | ||||
|             } | ||||
|          } | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    return sitesAdded; | ||||
| } | ||||
| 
 | ||||
| static bool ValidateJsonEntry(const boost::json::object& o) | ||||
| { | ||||
|    return (o.contains("type") && o.at("type").is_string() &&       //
 | ||||
|            o.contains("id") && o.at("id").is_string() &&           //
 | ||||
|            o.contains("lat") && o.at("lat").is_double() &&         //
 | ||||
|            o.contains("lon") && o.at("lon").is_double() &&         //
 | ||||
|            o.contains("country") && o.at("country").is_string() && //
 | ||||
|            o.contains("state") && o.at("state").is_string() &&     //
 | ||||
|            o.contains("place") && o.at("place").is_string()); | ||||
| } | ||||
| 
 | ||||
| } // namespace config
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
							
								
								
									
										45
									
								
								scwx-qt/source/scwx/qt/config/radar_site.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								scwx-qt/source/scwx/qt/config/radar_site.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <memory> | ||||
| #include <string> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace config | ||||
| { | ||||
| 
 | ||||
| class RadarSiteImpl; | ||||
| 
 | ||||
| class RadarSite | ||||
| { | ||||
| public: | ||||
|    explicit RadarSite(); | ||||
|    ~RadarSite(); | ||||
| 
 | ||||
|    RadarSite(const RadarSite&) = delete; | ||||
|    RadarSite& operator=(const RadarSite&) = delete; | ||||
| 
 | ||||
|    RadarSite(RadarSite&&) noexcept; | ||||
|    RadarSite& operator=(RadarSite&&) noexcept; | ||||
| 
 | ||||
|    std::string type() const; | ||||
|    std::string id() const; | ||||
|    double      latitude() const; | ||||
|    double      longitude() const; | ||||
|    std::string country() const; | ||||
|    std::string state() const; | ||||
|    std::string place() const; | ||||
| 
 | ||||
|    static std::shared_ptr<RadarSite> Get(const std::string& id); | ||||
| 
 | ||||
|    static size_t ReadConfig(const std::string& path); | ||||
| 
 | ||||
| private: | ||||
|    std::unique_ptr<RadarSiteImpl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace config
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
|  | @ -3,6 +3,8 @@ | |||
| #include <fstream> | ||||
| 
 | ||||
| #include <boost/log/trivial.hpp> | ||||
| #include <QFile> | ||||
| #include <QTextStream> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -27,6 +29,9 @@ static void PrettyPrintJson(std::ostream&             os, | |||
|                             boost::json::value const& jv, | ||||
|                             std::string*              indent = nullptr); | ||||
| 
 | ||||
| static boost::json::value ReadJsonFile(QFile& file); | ||||
| static boost::json::value ReadJsonStream(std::istream& is); | ||||
| 
 | ||||
| bool FromJsonInt64(const boost::json::object& json, | ||||
|                    const std::string&         key, | ||||
|                    int64_t&                   value, | ||||
|  | @ -117,13 +122,56 @@ bool FromJsonString(const boost::json::object& json, | |||
| 
 | ||||
| boost::json::value ReadJsonFile(const std::string& path) | ||||
| { | ||||
|    std::ifstream ifs {path}; | ||||
|    std::string   line; | ||||
|    boost::json::value json; | ||||
| 
 | ||||
|    if (path.starts_with(":")) | ||||
|    { | ||||
|       QFile file(path.c_str()); | ||||
|       json = ReadJsonFile(file); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       std::ifstream ifs {path}; | ||||
|       json = ReadJsonStream(ifs); | ||||
|    } | ||||
| 
 | ||||
|    return json; | ||||
| } | ||||
| 
 | ||||
| static boost::json::value ReadJsonFile(QFile& file) | ||||
| { | ||||
|    boost::json::value json; | ||||
| 
 | ||||
|    if (file.open(QIODevice::ReadOnly)) | ||||
|    { | ||||
|       QTextStream jsonStream(&file); | ||||
|       jsonStream.setEncoding(QStringConverter::Utf8); | ||||
| 
 | ||||
|       std::string        jsonSource = jsonStream.readAll().toStdString(); | ||||
|       std::istringstream is {jsonSource}; | ||||
| 
 | ||||
|       json = ReadJsonStream(is); | ||||
| 
 | ||||
|       file.close(); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) | ||||
|          << logPrefix_ << "Could not open file for reading: \"" | ||||
|          << file.fileName().toStdString() << "\""; | ||||
|    } | ||||
| 
 | ||||
|    return json; | ||||
| } | ||||
| 
 | ||||
| static boost::json::value ReadJsonStream(std::istream& is) | ||||
| { | ||||
|    std::string line; | ||||
| 
 | ||||
|    boost::json::stream_parser p; | ||||
|    boost::json::error_code    ec; | ||||
| 
 | ||||
|    while (std::getline(ifs, line)) | ||||
|    while (std::getline(is, line)) | ||||
|    { | ||||
|       p.write(line, ec); | ||||
|       if (ec) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat