📄 latlon.cpp
字号:
#include "latlon.h"#include <boost/tokenizer.hpp>#include <boost/tuple/tuple.hpp>#include "datatypes.h"#include "exceptions.h"#include <sstream>namespace{ using namespace gpsmgr; using namespace gpsmgr::exceptions; void checkLat(BrgDegs val) { if (val < -90.0 || val > 90.0) throw exceptions::Exception<IllegalValue>("Latitude values must be between -90.0 and 90.0"); } void checkLon(BrgDegs val) { if (val < -180.0 || val > 180.0) throw exceptions::Exception<IllegalValue>("Longitude values must be between -180.0 and 180.0"); } typedef boost::tuple<short, short, BrgDegs> Components; Components valueToComponents(BrgDegs val) { if (val < 0.0) val = std::fabs(val); short deg = static_cast<short>(val); BrgDegs rem = val - static_cast<BrgDegs>(deg); short min = static_cast<short>(rem * 60.0); rem -= static_cast<BrgDegs>(min) / 60.0; BrgDegs sec = static_cast<BrgDegs>(rem * 3600.0); return boost::make_tuple(deg, min, sec); } BrgDegs componentsToValue(const Components& comp) { BrgDegs rval = comp.get<0>(); rval += comp.get<1>() / 60.0; rval += comp.get<2>() / 3600.0; return rval; } }namespace gpsmgr{ //-------------------------------------------------------------------------- Latitude::Latitude() : mValue (0.0) {} Latitude::Latitude(BrgDegs val) : mValue (val) { checkLat(val); } BrgDegs Latitude::value() const { return mValue; } void Latitude::setValue(BrgDegs val) { checkLat(val); mValue = val; } //-------------------------------------------------------------------------- Longitude::Longitude() : mValue (0.0) {} Longitude::Longitude(BrgDegs val) : mValue (val) { checkLon(val); } BrgDegs Longitude::value() const { return mValue; } void Longitude::setValue(BrgDegs val) { checkLon(val); mValue = val; } //-------------------------------------------------------------------------- LatLon::LatLon() {} LatLon::LatLon(const Latitude& lat, const Longitude& lon) : mLat (lat), mLon (lon) {} const Latitude& LatLon::lat() const { return mLat; } void LatLon::setLat(const Latitude& lat) { mLat = lat; } const Longitude& LatLon::lon() const { return mLon; } void LatLon::setLon(const Longitude& lon) { mLon = lon; } //-------------------------------------------------------------------------- bool operator<(const Latitude& lhs, const Latitude& rhs) { return rhs.value() < rhs.value(); } bool operator<(const Longitude& lhs, const Longitude& rhs) { return lhs.value() < rhs.value(); } bool operator<(const LatLon& lhs, const LatLon& rhs) { if (lhs.lat() != rhs.lat()) return lhs.lat() < rhs.lat(); else return lhs.lon() < rhs.lon(); } bool operator==(const Latitude& lhs, const Latitude& rhs) { return lhs.value() == rhs.value(); } bool operator==(const Longitude& lhs, const Longitude& rhs) { return lhs.value() == rhs.value(); } bool operator==(const LatLon& lhs, const LatLon& rhs) { return (lhs.lat() == rhs.lat() && rhs.lon() == rhs.lon()); } bool operator!=(const Latitude& lhs, const Latitude& rhs) { return !(rhs == lhs); } bool operator!=(const Longitude& lhs, const Longitude& rhs) { return !(rhs == lhs); } bool operator!=(const LatLon& lhs, const LatLon& rhs) { return !(rhs == lhs); } ostream& operator<<(ostream& os, const Latitude& lat) { BrgDegs val = lat.value(); bool south = val < 0.0; Components comp = valueToComponents(val); os << comp.get<0>() << ":" << comp.get<1>() << ":" << comp.get<2>() << ":"; if (south) os << "S"; else os << "N"; return os; } ostream& operator<<(ostream& os, const Longitude& lon) { BrgDegs val = lon.value(); bool west = val < 0.0; Components comp = valueToComponents(val); os << comp.get<0>() << ":" << comp.get<1>() << ":" << comp.get<2>() << ":"; if (west) os << "W"; else os << "E"; return os; } ostream& operator<<(ostream& os, const LatLon& ll) { os << ll.lat() << " " << ll.lon(); return os; } istream& operator>>(istream& is, Latitude& lat) { using namespace boost; string latstr; is >> latstr; typedef tokenizer<char_separator<char> > tokenizer; char_separator<char> sep(":"); tokenizer tokens(latstr, sep); std::vector<string> toks(tokens.begin(), tokens.end()); if (toks.size() != 4) throw Exception<ParseError>("Latitude must be of form <deg>:<min>:<sec>:<N/S>"); Components comps; istringstream deg_iss(toks[0]); deg_iss >> comps.get<0>(); istringstream min_iss(toks[1]); min_iss >> comps.get<1>(); istringstream sec_iss(toks[2]); sec_iss >> comps.get<2>(); BrgDegs val = componentsToValue(comps); if (toks[3] == "S") val *= -1; else if (toks[3] != "N") throw Exception<ParseError>("Latitude must be of form <deg>:<min>:<sec>:<N/S>"); Latitude rval; try { rval.setValue(val); } catch (Exception<IllegalValue>& e) { throw Exception<ParseError>(e.what()); } lat = rval; return is; } istream& operator>>(istream& is, Longitude& lon) { using namespace boost; string lonstr; is >> lonstr; typedef tokenizer<char_separator<char> > tokenizer; char_separator<char> sep(":"); tokenizer tokens(lonstr, sep); std::vector<string> toks(tokens.begin(), tokens.end()); if (toks.size() != 4) throw Exception<ParseError>("Longitude must be of form <deg>:<min>:<sec>:<E/W>"); Components comps; istringstream deg_iss(toks[0]); deg_iss >> comps.get<0>(); istringstream min_iss(toks[1]); min_iss >> comps.get<1>(); istringstream sec_iss(toks[2]); sec_iss >> comps.get<2>(); BrgDegs val = componentsToValue(comps); if (toks[3] == "W") val *= -1; else if (toks[3] != "E") throw Exception<ParseError>("Longitude must be of form <deg>:<min>:<sec>:<E/W>"); Longitude rval; try { rval.setValue(val); } catch (Exception<IllegalValue>& e) { throw Exception<ParseError>(e.what()); } lon = rval; return is; } istream& operator>>(istream& is, LatLon& ll) { Latitude lat; is >> lat; Longitude lon; is >> lon; LatLon rval(lat, lon); ll = rval; return is; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -