Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef SNIPPETS_LATLON_ENCODER_H
00038 #define SNIPPETS_LATLON_ENCODER_H
00039 #include <stdexcept>
00040 #include <cmath>
00041
00042 #define PP_ADD_CASE1(x) \
00043 case x: \
00044 this->latlonToBits<x>(lat,lon); \
00045 break; \
00046
00047 #define PP_ADD_CASE2(x) \
00048 case x: \
00049 this->bitsToLatlon<x>(lat,lon); \
00050 break; \
00051
00052 namespace labust
00053 {
00054 namespace tools
00055 {
00063 class LatLon2Bits
00064 {
00065 public:
00066 void convert(double lat, double lon, int bits = 7);
00067
00068 int64_t lat, lon;
00069
00070 protected:
00071 template <size_t precission>
00072 void latlonToBits(double lat, double lon);
00073 };
00074
00075 template <>
00076 inline void LatLon2Bits::latlonToBits<22>(double lat, double lon)
00077 {
00078 double min = (lon - int(lon))*60;
00079 this->lon = int((int(lon)+180)*10000 + min*100);
00080
00081 min = (lat - int(lat))*60;
00082 this->lat = int((int(lat)+90)*10000 + min*100);
00083 }
00084 template <>
00085 inline void LatLon2Bits::latlonToBits<18>(double lat, double lon)
00086 {
00087
00088
00089 this->lat = int((fabs(lat) - int(fabs(lat)))*1000000)%100000;
00090 this->lon = int((fabs(lon) - int(fabs(lon)))*1000000)%100000;
00091 }
00092
00093 template <>
00094 inline void LatLon2Bits::latlonToBits<14>(double lat, double lon)
00095 {
00096
00097
00098
00099
00100
00101 this->lat = int((fabs(lat) - int(fabs(lat)))*1000000)%10000;
00102 this->lon = int((fabs(lon) - int(fabs(lon)))*1000000)%10000;
00103 }
00104
00105 template <>
00106 inline void LatLon2Bits::latlonToBits<10>(double lat, double lon)
00107 {
00108 this->latlonToBits<14>(lat,lon);
00109 this->lat/=10;
00110 this->lon/=10;
00111 }
00112 template <>
00113 inline void LatLon2Bits::latlonToBits<7>(double lat, double lon)
00114 {
00115 this->latlonToBits<14>(lat,lon);
00116 this->lat%=100;
00117 this->lon%=100;
00118 }
00119
00120 inline void LatLon2Bits::convert(double lat, double lon, int bits)
00121 {
00122 switch (bits)
00123 {
00124 case 0: break;
00125 PP_ADD_CASE1(7);
00126 PP_ADD_CASE1(10);
00127 PP_ADD_CASE1(14);
00128 PP_ADD_CASE1(18);
00129 PP_ADD_CASE1(22);
00130 default:
00131 throw std::runtime_error("LatLon2Bits: Missing lat-lon conversion definition.");
00132 }
00133 }
00134
00144 class Bits2LatLon
00145 {
00146 public:
00147 Bits2LatLon(double ilat = 0, double ilon = 0):
00148 latitude(ilat),
00149 longitude(ilon),
00150 initLat(0),
00151 initLon(0)
00152 {
00153 this->normalize();
00154 };
00155
00156 void convert(double lat, double lon, int bits = 7);
00157
00158 void setInitLatLon(double lat, double lon)
00159 {
00160 latitude = lat;
00161 longitude = lon;
00162 normalize();
00163 }
00164
00165 double latitude, longitude;
00166 double initLat, initLon;
00167
00168 protected:
00169 template <size_t precission>
00170 void bitsToLatlon(double lat, double lon){};
00171 void normalize()
00172 {
00173
00174
00175 initLat = latitude;
00176 initLon = longitude;
00177 }
00178 };
00179
00180 template <>
00181 inline void Bits2LatLon::bitsToLatlon<22>(double lat, double lon)
00182 {
00183 double rem = (lat/10000 - int(lat/10000))*10000;
00184 initLat = this->latitude = int(lat)/10000 + rem/6000 - 90;
00185 rem = (lon/10000 - int(lon/10000))*10000;
00186 initLon = this->longitude = int(lon)/10000 + rem / 6000 - 180;
00187 }
00188 template <>
00189 inline void Bits2LatLon::bitsToLatlon<18>(double lat, double lon)
00190 {
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 latitude = int(initLat*10)/10.0 + (initLat>=0?1:-1)*lat/1000000;
00206 longitude = int(initLon*10)/10.0 + (initLon>=0?1:-1)*lon/1000000;
00207 }
00208 template <>
00209 inline void Bits2LatLon::bitsToLatlon<14>(double lat, double lon)
00210 {
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 latitude = int(initLat*100)/100.0 + (initLat>=0?1:-1)*lat/1000000;
00229 longitude = int(initLon*100)/100.0 + (initLon>=0?1:-1)*lon/1000000;
00230 }
00231 template <>
00232 inline void Bits2LatLon::bitsToLatlon<10>(double lat, double lon)
00233 {
00234 latitude = int(initLat*100)/100.0 + (initLat>=0?1:-1)*lat/100000;
00235 longitude = int(initLon*100)/100.0 + (initLon>=0?1:-1)*lon/100000;
00236 }
00237 template <>
00238 inline void Bits2LatLon::bitsToLatlon<7>(double lat, double lon)
00239 {
00240 throw std::runtime_error("Bits2LatLon: decompression for 7 bits not implemented.");
00241 }
00242
00243 inline void Bits2LatLon::convert(double lat, double lon, int bits)
00244 {
00245 switch (bits)
00246 {
00247 case 0: break;
00248
00249 PP_ADD_CASE2(10);
00250 PP_ADD_CASE2(14);
00251 PP_ADD_CASE2(18);
00252 PP_ADD_CASE2(22);
00253 default:
00254 throw std::runtime_error("LatLon2Bits: Missing lat-lon conversion definition.");
00255 }
00256 }
00257 }
00258 }
00259
00260 #undef PP_ADD_CASE1
00261 #undef PP_ADD_CASE2
00262
00263
00264 #endif
00265
00266
00267