Osmium
0.1
|
00001 #ifndef OSMIUM_OSM_POSITION_HPP 00002 #define OSMIUM_OSM_POSITION_HPP 00003 00004 /* 00005 00006 Copyright 2011 Jochen Topf <jochen@topf.org> and others (see README). 00007 00008 This file is part of Osmium (https://github.com/joto/osmium). 00009 00010 Osmium is free software: you can redistribute it and/or modify it under the 00011 terms of the GNU Lesser General Public License or (at your option) the GNU 00012 General Public License as published by the Free Software Foundation, either 00013 version 3 of the Licenses, or (at your option) any later version. 00014 00015 Osmium is distributed in the hope that it will be useful, but WITHOUT ANY 00016 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 00017 PARTICULAR PURPOSE. See the GNU Lesser General Public License and the GNU 00018 General Public License for more details. 00019 00020 You should have received a copy of the Licenses along with Osmium. If not, see 00021 <http://www.gnu.org/licenses/>. 00022 00023 */ 00024 00025 #include <stdint.h> 00026 #include <ostream> 00027 #include <limits> 00028 #include <math.h> 00029 00030 #ifdef OSMIUM_WITH_GEOS 00031 # include <geos/geom/Coordinate.h> 00032 #endif 00033 00034 namespace Osmium { 00035 00036 namespace OSM { 00037 00044 class Position { 00045 00046 public: 00047 00048 explicit Position() : m_x(std::numeric_limits<int32_t>::max()), m_y(std::numeric_limits<int32_t>::max()) { 00049 } 00050 00051 explicit Position(int32_t x, int32_t y) : m_x(x), m_y(y) { 00052 } 00053 00054 explicit Position(double lon, double lat) : m_x(double_to_fix(lon)), m_y(double_to_fix(lat)) { 00055 } 00056 00057 bool defined() const { 00058 return m_x != std::numeric_limits<int32_t>::max() && m_x != std::numeric_limits<int32_t>::min(); 00059 } 00060 00061 int32_t x() const { 00062 return m_x; 00063 } 00064 00065 int32_t y() const { 00066 return m_y; 00067 } 00068 00069 double lon() const { 00070 return fix_to_double(m_x); 00071 } 00072 00073 double lat() const { 00074 return fix_to_double(m_y); 00075 } 00076 00077 Position& lon(double lon) { 00078 m_x = double_to_fix(lon); 00079 return *this; 00080 } 00081 00082 Position& lat(double lat) { 00083 m_y = double_to_fix(lat); 00084 return *this; 00085 } 00086 00087 #ifdef OSMIUM_WITH_JAVASCRIPT 00088 v8::Handle<v8::Array> js_to_array() const { 00089 v8::HandleScope scope; 00090 v8::Local<v8::Array> array = v8::Array::New(2); 00091 array->Set(0, v8::Number::New(lon())); 00092 array->Set(1, v8::Number::New(lat())); 00093 return scope.Close(array); 00094 } 00095 #endif // OSMIUM_WITH_JAVASCRIPT 00096 00097 friend bool operator==(const Position& p1, const Position& p2) { 00098 return p1.m_x == p2.m_x && p1.m_y == p2.m_y; 00099 } 00100 00101 friend bool operator!=(const Position& p1, const Position& p2) { 00102 return !(p1 == p2); 00103 } 00104 00105 friend std::ostream& operator<<(std::ostream& out, const Position& position) { 00106 out << '(' << position.lon() << ',' << position.lat() << ')'; 00107 return out; 00108 } 00109 00111 operator uint32_t() const { 00112 int32_t x = 180 + m_x / precision; 00113 int32_t y = 90 - m_y / precision; 00114 00115 if (x < 0) x = 0; 00116 if (y < 0) y = 0; 00117 if (x >= 360) x = 359; 00118 if (y >= 180) y = 179; 00119 00120 return 360 * y + x; 00121 } 00122 00123 #ifdef OSMIUM_WITH_GEOS 00124 00127 operator geos::geom::Coordinate() const { 00128 geos::geom::Coordinate c(lon(), lat()); 00129 return c; 00130 } 00131 #endif 00132 00133 private: 00134 00135 static const int precision = 10000000; 00136 00137 int32_t m_x; 00138 int32_t m_y; 00139 00140 static int32_t double_to_fix(double c) { 00141 return round(c * precision); 00142 } 00143 00144 static double fix_to_double(int32_t c) { 00145 return static_cast<double>(c) / precision; 00146 } 00147 00148 }; 00149 00150 } // namespace OSM 00151 00152 } // namespace Osmium 00153 00154 #endif // OSMIUM_OSM_POSITION_HPP