NAVTOR SDK  v.3.0
Software Development Kit for fast and efficient development of ECDIS, ECS and generic marine applications
string_coordinate_conversions.h
Go to the documentation of this file.
1 // found in the LICENSE file.
10 
11 #ifndef SDK_BASE_STRING_COORDINATES_CONVERSIONS_H_
12 #define SDK_BASE_STRING_COORDINATES_CONVERSIONS_H_
13 
14 #include <string.h>
15 #include <string>
16 #include <vector>
17 #include <stdio.h>
18 #include <stdarg.h>
19 #include <base/inc/platform.h>
20 #include <base/inc/base_types.h>
21 
22 namespace sdk {
23 namespace conversions {
24 
25 inline SDKUInt32 MulDivUInt32(SDKUInt32 number, SDKUInt32 numerator,
26  SDKUInt32 denominator) {
27  SDKUInt64 intermediate = static_cast<SDKUInt64>(number) * numerator;
28  return denominator ? ((intermediate /= denominator) <= SDK_MAX_UINT32 ?
29  static_cast<SDKUInt32>(intermediate) : SDK_MAX_UINT32) :
30  static_cast<SDKUInt32>(intermediate >> 32);
31 }
32 
33 inline std::string CoordStrPrintf(const std::string& format,
34  char* coord_str, size_t coord_str_size,...) {
35 
36  va_list dividers;
37  va_start(dividers, coord_str_size);
38 
39 #if defined(SDK_CC_MSVC)
40  vsprintf_s(coord_str, coord_str_size, format.c_str(), dividers);
41 #else
42  vsprintf(coord_str, format.c_str(), dividers);
43 #endif
44  va_end(dividers);
45  return coord_str;
46 }
47 
50 static inline std::string GeoIntToString(SDKUInt32 coord,
51  const std::string& format, char positive, char negative, SDKUInt32 max_value,
52  const SDKUInt32* dividers, SDKUInt32 divider_count) {
53 
54  bool sign = true;
55  if (static_cast<SDKInt32>(coord) < 0) {
56  coord = static_cast<SDKUInt32>(-static_cast<SDKInt32>(coord));
57  sign = false;
58  }
59 
60  if (coord > max_value)
61  return "";
62 
63  typedef std::vector<SDKUInt32> Dividers;
64  Dividers dividers_vec(dividers, &dividers[divider_count]);
65 
66  SDKUInt32 scale = 1;
67  for (Dividers::const_iterator it = dividers_vec.begin();
68  it != dividers_vec.end(); ++it) {
69  scale = scale * static_cast<SDKUInt32>(*it);
70  }
71 
72  coord += (0x20000000UL / scale);
73 
74  scale = 1;
75 
76  for (Dividers::iterator it = dividers_vec.begin();
77  it != dividers_vec.end(); ++it) {
78  scale = scale * static_cast<SDKUInt32>(*it);
79  SDKUInt32 tmp = MulDivUInt32(coord, scale, 0x40000000UL);
80  coord -= MulDivUInt32(tmp, 0x40000000UL, scale);
81  (*it) = tmp;
82  }
83 
84  char coord_str[32] = {0};
85  switch(dividers_vec.size()) {
86  case 3:
87  CoordStrPrintf(format, coord_str, sizeof(coord_str),
88  dividers_vec[0], dividers_vec[1], dividers_vec[2]);
89  break;
90  default:
91  break;
92  }
93 
94  char* sign_pos = strchr(coord_str, '\\');
95 
96  if (sign_pos)
97  *sign_pos = sign ? positive : negative;
98 
99  return std::string(coord_str);
100 }
101 
103 static const char* kLatHemispherePostfix ="%02u#%02u.%04u\'\\";
104 static const char* kLonHemispherePostfix = "%03u#%02u.%04u\'\\";
105 static const char* kLatHemispherePrefix = "\\ %02u#%02u.%04u\'";
106 static const char* kLonHemispherePrefix = "\\ %03u#%02u.%04u\'";
107 static const char* kLatHemispherePostfixSpaced = "%02u# %02u.%04u\' \\";
108 static const char* kLonHemispherePostfixSpaced = "%03u# %02u.%04u\' \\";
109 static const char* kLatHemispherePrefixSpaced = "\\ %02u# %02u.%04u\'";
110 static const char* kLonHemispherePrefixSpaced = "\\ %03u# %02u.%04u\'";
111 static const SDKUInt32 kDividers[3] = { 90, 60, 10000 };
112 
114 static const char* kLatHemispherePostfix3 = "%02u#%02u.%03u\'\\";
115 static const char* kLonHemispherePostfix3 = "%03u#%02u.%03u\'\\";
116 static const char* kLatHemispherePrefix3 = "\\ %02u#%02u.%03u\'";
117 static const char* kLonHemispherePrefix3 = "\\ %03u#%02u.%03u\'";
118 static const char* kLatHemispherePostfix3Spaced = "%02u# %02u.%03u\' \\";
119 static const char* kLonHemispherePostfix3Spaced = "%03u# %02u.%03u\' \\";
120 static const char* kLatHemispherePrefix3Spaced = "\\ %02u# %02u.%03u\'";
121 static const char* kLonHemispherePrefix3Spaced = "\\ %03u# %02u.%03u\'";
122 static const SDKUInt32 kDividers3[3] = { 90, 60, 1000 };
123 
124 static const unsigned char kDegreeSignB = 0xB0;
125 static const std::wstring::value_type kDegreeSignW = 0xB0;
126 
129 inline std::string LatToString(SDKInt32 lat) {
130  std::string res = GeoIntToString(static_cast<SDKUInt32>(lat),
132  'N',
133  'S',
134  0x40000000UL,
135  kDividers,
136  sizeof(kDividers)/sizeof(kDividers[0]));
137  size_t pos = res.find_first_of("#");
138  if (pos != std::string::npos) {
139  res[pos] = kDegreeSignB;
140  }
141  return res;
142 }
143 
146 inline std::string LonToString(SDKInt32 lon) {
147  std::string res = GeoIntToString(static_cast<SDKUInt32>(lon),
148  kLonHemispherePostfix,
149  'E',
150  'W',
151  0x80000000UL,
152  kDividers,
153  sizeof(kDividers)/sizeof(kDividers[0]));
154  size_t pos = res.find_first_of("#");
155  if (pos != std::string::npos) {
156  res[pos] = kDegreeSignB;
157  }
158  return res;
159 }
160 
163 inline std::wstring LatToWString(SDKInt32 lat) {
164  std::string ascii = GeoIntToString(static_cast<SDKUInt32>(lat),
166  'N',
167  'S',
168  0x40000000UL,
169  kDividers,
170  sizeof(kDividers)/sizeof(kDividers[0]));
171 
172  std::wstring res = std::wstring(ascii.begin(), ascii.end());
173  size_t pos = res.find_first_of(L"#");
174  if (pos != std::wstring::npos) {
175  res[pos] = kDegreeSignW;
176  }
177  return res;
178 }
179 
182 inline std::wstring LonToWString(SDKInt32 lon) {
183  std::string ascii = GeoIntToString(static_cast<SDKUInt32>(lon),
184  kLonHemispherePostfix,
185  'E',
186  'W',
187  0x80000000UL,
188  kDividers,
189  sizeof(kDividers)/sizeof(kDividers[0]));
190 
191  std::wstring res = std::wstring(ascii.begin(), ascii.end());
192  size_t pos = res.find_first_of(L"#");
193  if (pos != std::wstring::npos) {
194  res[pos] = kDegreeSignW;
195  }
196  return res;
197 }
198 
199 } // conversions
200 } // namespace sdk
201 
202 #endif
base_types.h
SDK base types.
sdk::conversions::LatToString
std::string LatToString(SDKInt32 lat)
Converts the latitude of a geographic position to a string.
Definition: string_coordinate_conversions.h:129
sdk::conversions::LatToWString
std::wstring LatToWString(SDKInt32 lat)
Converts the latitude of a geographic position to a wide string.
Definition: string_coordinate_conversions.h:163
platform.h
Describes the platform constants.
sdk::conversions::LonToWString
std::wstring LonToWString(SDKInt32 lon)
Converts the longitude of a geographic position to a wide string.
Definition: string_coordinate_conversions.h:182
sdk::conversions::kLatHemispherePostfix
static const char * kLatHemispherePostfix
4 decimals of minutes
Definition: string_coordinate_conversions.h:103
SDK_MAX_UINT32
static const SDKUInt32 SDK_MAX_UINT32
Max limit of 32-bit unsigned integer.
Definition: platform.h:179
sdk::conversions::GeoIntToString
static std::string GeoIntToString(SDKUInt32 coord, const std::string &format, char positive, char negative, SDKUInt32 max_value, const SDKUInt32 *dividers, SDKUInt32 divider_count)
Converts coordinates of a geographic position to a string.
Definition: string_coordinate_conversions.h:50
sdk::conversions::LonToString
std::string LonToString(SDKInt32 lon)
Converts the longitude of a geographic position to a string.
Definition: string_coordinate_conversions.h:146
sdk::conversions::kLatHemispherePostfix3
static const char * kLatHemispherePostfix3
3 decimals of minutes
Definition: string_coordinate_conversions.h:114