63 degrees = angle_16th_secs / (3600 * 16);
64 angle_16th_secs = angle_16th_secs % (3600 * 16);
65 minutes = angle_16th_secs / (60 * 16);
66 angle_16th_secs = angle_16th_secs % (60 * 16);
67 seconds = angle_16th_secs / 16;
68 sec16ths = angle_16th_secs % 16;
76 if (
rare(lat < -90.0 || lat > 90.0)) {
81 lon = fmod(lon, 360.0);
86 int lat_16ths, lon_16ths;
87 lat_16ths = lround((lat + 90.0) * 57600.0);
88 if (lat_16ths == 0 || lat_16ths == 57600 * 180) {
91 lon_16ths = lround(lon * 57600.0);
92 if (lon_16ths == 57600 * 360) {
100 size_t old_len = result.size();
101 result.resize(old_len + 6);
106 result[old_len] = char(dd >> 8);
107 result[old_len + 1] = char(dd & 0xff);
110 result[old_len + 2] = char(((lat_dms.
minutes / 4) << 4) |
114 result[old_len + 3] = char(
117 ((lat_dms.
seconds / 15) << 2) |
121 result[old_len + 4] = char(
122 ((lat_dms.
seconds % 15) << 4) |
126 result[old_len + 5] = char(
136 double & lat_ref,
double & lon_ref)
138 const unsigned char * ptr
139 =
reinterpret_cast<const unsigned char *
>(value);
140 unsigned tmp = (ptr[0] & 0xff) << 8 | (ptr[1] & 0xff);
145 double lat_m = (tmp >> 4) * 4;
146 double lon_m = (tmp & 0xf) * 4;
150 lat_m += (tmp >> 6) & 3;
151 lon_m += (tmp >> 4) & 3;
152 double lat_s = ((tmp >> 2) & 3) * 15;
153 double lon_s = (tmp & 3) * 15;
157 lat_s += (tmp >> 4) & 0xf;
162 lat_s += ((tmp >> 4) / 16.0);
163 lon_s += ((tmp & 0xf) / 16.0);
167 lat_m += lat_s / 60.0;
168 lon_m += lon_s / 60.0;
171 lat_ref += lat_m / 60.0;
172 lon_ref += lon_m / 60.0;
182 lat_16ths = lround((lat + 90.0) * 57600.0);
183 lon_16ths = lround(lon * 57600.0);
184 if (lon_16ths == 57600 * 360) {
190 (
double lat1,
double lon1_,
double lat2,
double lon2_)
191 : lon1(lon1_), lon2(lon2_),
192 min_lat(lat1), max_lat(lat2),
196 lon1 = fmod(lon1, 360.0);
201 lon2 = fmod(lon2, 360.0);
207 int lat_16ths, lon_16ths;
209 if (lat_16ths == 0 || lat_16ths == 57600 * 180) {
210 include_poles =
true;
212 unsigned dd = lat_16ths / (3600 * 16) + (lon_16ths / (3600 * 16)) * 181;
213 start1 = char(dd >> 8);
216 if (lat_16ths == 0 || lat_16ths == 57600 * 180) {
217 include_poles =
true;
219 dd = lat_16ths / (3600 * 16) + (lon_16ths / (3600 * 16)) * 181;
220 start2 = char(dd >> 8);
222 discontinuous_longitude_range = (lon1 > lon2);
228 double & lon_ref)
const 230 unsigned char start = value[0];
231 if (discontinuous_longitude_range) {
234 if (start2 < start && start < start1) {
235 if (!(include_poles && start == 0))
240 if (start < start1 || start2 < start) {
241 if (!(include_poles && start == 0))
247 if (lat < min_lat || lat > max_lat) {
250 if (lat == -90 || lat == 90) {
257 if (discontinuous_longitude_range) {
258 if (lon2 < lon && lon < lon1)
261 if (lon < lon1 || lon2 < lon)
DegreesMinutesSeconds(int angle_16th_secs)
Initialise with a (positive) angle, as an integer representing the number of 16ths of a second...
int minutes
Number of minutes: 0 to 59.
int sec16ths
Number of 16ths of a second: 0 to 15.
void decode(const char *value, size_t len, double &lat_ref, double &lon_ref)
Decode a coordinate from a buffer.
int degrees
Number of degrees.
bool encode(double lat, double lon, std::string &result)
Encode a coordinate and append it to a string.
bool decode(const std::string &value, double &lat_ref, double &lon_ref) const
Decode a coordinate.
int seconds
Number of seconds: 0 to 59.
Encodings for geospatial coordinates.
Angles, split into degrees, minutes and seconds.
static void calc_latlon_16ths(double lat, double lon, int &lat_16ths, int &lon_16ths)
Calc latitude and longitude in integral number of 16ths of a second.
DecoderWithBoundingBox(double lat1, double lon1, double lat2, double lon2)
Create a decoder with a bounding box.