latlon_encoder.h
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, LABUST, UNIZG-FER
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the LABUST nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  *  Author: Dula Nad
00035  *  Created: 29.04.2013.
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                         //this->lat = int((lat - int(lat))*600000)%100000;
00088                         //this->lon = int((lon - int(lon))*600000)%100000;
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                         //double min = (lon - int(lon))*60;
00097                         //this->lon = int((min - int(min))*10000);
00098 
00099                         //min = (lat - int(lat))*60;
00100                         //this->lat = int((min - int(min))*10000);
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                                 //initLat = (floor(latitude*6000)) / 6000.0;
00174                                 //initLon = (floor(longitude*6000)) / 6000.0;
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                         /*double rem = int(((initLat*60)-int(initLat*60))*10);
00192                         //rem = lat/10000.0 - rem;
00193                         //int sgn = (rem >=0) ? 1: -1;
00194                         //latitude = (((fabs(rem) > 5)? floor(initLat*6+sgn):floor(initLat*6)) + lat/100000.0)/6;
00195                         latitude = floor(initLat*6)) + lat/100000.0)/6;
00196 
00197                         rem = int(((initLon*60)-int(initLon*60))*10);
00198                         rem = lon/10000.0 - rem;
00199                         sgn = (rem >=0) ? 1: -1;
00200                         longitude = (((fabs(rem) > 5)? floor(initLon*6+sgn*rem):floor(initLon*6)) + lon/100000.0)/6;
00201 
00202                         initLat = (floor(latitude*6000)) / 6000.0;
00203                   initLon = (floor(longitude*6000)) / 6000.0;
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                         /*if ((lat/10000.0 - fmod(initLat*60,1)) < -0.5)
00212                                 latitude = (floor(initLat*60 + 1) + lat/10000.0)/60;
00213                         else if ((lat/10000.0 - fmod(initLat*60,1)) > 0.5)
00214                                 latitude = (floor(initLat*60 - 1) + lat/10000.0)/60;
00215                         else
00216                           latitude = (floor(initLat*60) + lat/10000.0)/60;
00217 
00218                         if ((lon/10000.0 - fmod(initLon*60,1)) < -0.5)
00219                                 longitude = (floor(initLon*60 + 1) + lon/10000.0)/60;
00220                         else if ((lon/10000.0 - fmod(initLon*60,1)) > 0.5)
00221                                 longitude = (floor(initLon*60 - 1) + lon/10000.0)/60;
00222                         else
00223                           longitude = (floor(initLon*60) + lon/10000.0)/60;
00224 
00225                         initLat = (floor(latitude*6000)) / 6000.0;
00226                         initLon = (floor(longitude*6000)) / 6000.0;*/
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                                         //PP_ADD_CASE2(7);
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 /* USBL_COMMS_LATLON_ENCODER_H */
00264 #endif
00265 
00266 
00267 


snippets
Author(s): Gyula Nagy
autogenerated on Fri Aug 28 2015 11:22:33