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),
207 int lat_16ths, lon_16ths;
209 if (lat_16ths == 0 || lat_16ths == 57600 * 180) {
212 unsigned dd = lat_16ths / (3600 * 16) + (lon_16ths / (3600 * 16)) * 181;
216 if (lat_16ths == 0 || lat_16ths == 57600 * 180) {
219 dd = lat_16ths / (3600 * 16) + (lon_16ths / (3600 * 16)) * 181;
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)
bool decode(const std::string &value, double &lat_ref, double &lon_ref) const
Decode a coordinate.
unsigned char start1
First byte of encoded form of coordinates with lon1.
double lon2
Longitude at eastern edge of bounding box.
unsigned char start2
First byte of encoded form of coordinates with lon2.
bool include_poles
True if either of the poles are included in the range.
double lon1
Longitude at western edge of bounding box.
DecoderWithBoundingBox(double lat1, double lon1, double lat2, double lon2)
Create a decoder with a bounding box.
bool discontinuous_longitude_range
Flag; true if the longitude range is discontinuous (ie, goes over the boundary at which longitudes wr...
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.
Encodings for geospatial coordinates.
bool encode(double lat, double lon, std::string &result)
Encode a coordinate and append it to a string.
void decode(const char *value, size_t len, double &lat_ref, double &lon_ref)
Decode a coordinate from a buffer.
Angles, split into degrees, minutes and seconds.
int sec16ths
Number of 16ths of a second: 0 to 15.
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 degrees
Number of degrees.
int seconds
Number of seconds: 0 to 59.