79 static char *
lwdouble_to_dms(
double val,
const char *pos_dir_symbol,
const char *neg_dir_symbol,
const char * format)
83 # define WORK_SIZE 1024
85 int current_piece = 0;
92 int compass_dir_piece = -1;
96 int deg_has_decpoint = 0;
97 int deg_dec_digits = 0;
102 int min_has_decpoint = 0;
103 int min_dec_digits = 0;
108 int sec_has_decpoint = 0;
109 int sec_dec_digits = 0;
114 int format_length = ((NULL == format) ? 0 : strlen(format));
118 int index, following_byte_index;
119 int multibyte_char_width = 1;
126 pieces[index][0] =
'\0';
130 if (0 == format_length)
133 format =
"D\xC2\xB0""M'S.SSS\"C";
134 format_length = strlen(format);
143 for (index = 0; index < format_length; index++)
145 char next_char = format[index];
152 deg_has_decpoint ? deg_dec_digits++ : deg_digits++;
158 deg_piece = current_piece;
161 lwerror(
"Bad format, cannot include degrees (DD.DDD) more than once.");
173 min_has_decpoint ? min_dec_digits++ : min_digits++;
179 min_piece = current_piece;
182 lwerror(
"Bad format, cannot include minutes (MM.MMM) more than once.");
194 sec_has_decpoint ? sec_dec_digits++ : sec_digits++;
200 sec_piece = current_piece;
203 lwerror(
"Bad format, cannot include seconds (SS.SSS) more than once.");
213 if (reading_deg || reading_min || reading_sec)
222 if (compass_dir_piece >= 0)
224 lwerror(
"Bad format, cannot include compass dir (C) more than once.");
227 compass_dir_piece = current_piece;
234 deg_has_decpoint = 1;
236 else if (reading_min)
238 min_has_decpoint = 1;
240 else if (reading_sec)
242 sec_has_decpoint = 1;
247 strncat(pieces[current_piece], &next_char, 1);
252 if (reading_deg || reading_min || reading_sec)
262 multibyte_char_width = 1;
263 if (next_char & 0x80)
265 if ((next_char & 0xF8) == 0xF0)
267 multibyte_char_width += 3;
269 else if ((next_char & 0xF0) == 0xE0)
271 multibyte_char_width += 2;
273 else if ((next_char & 0xE0) == 0xC0)
275 multibyte_char_width += 1;
279 lwerror(
"Bad format, invalid high-order byte found first, format string may not be UTF-8.");
282 if (multibyte_char_width > 1)
284 if (index + multibyte_char_width >= format_length)
286 lwerror(
"Bad format, UTF-8 character first byte found with insufficient following bytes, format string may not be UTF-8.");
288 for (following_byte_index = (index + 1); following_byte_index < (index + multibyte_char_width); following_byte_index++)
290 if ((format[following_byte_index] & 0xC0) != 0x80)
292 lwerror(
"Bad format, invalid byte found following leading byte of multibyte character, format string may not be UTF-8.");
297 strncat(pieces[current_piece], &(format[index]), multibyte_char_width);
299 index += multibyte_char_width - 1;
304 lwerror(
"Internal error, somehow needed more pieces than it should.");
309 lwerror(
"Bad format, degrees (DD.DDD) must be included.");
322 minutes = modf(val, °rees) * 60;
328 lwerror(
"Bad format, cannot include seconds (SS.SSS) without including minutes (MM.MMM).");
330 seconds = modf(minutes, &minutes) * 60;
334 round_pow = pow(10, sec_dec_digits);
335 if (floorf(seconds * round_pow) / round_pow >= 60)
344 if (compass_dir_piece >= 0)
346 strcpy(pieces[compass_dir_piece], is_negative ? neg_dir_symbol : pos_dir_symbol);
348 else if (is_negative)
354 if (deg_digits + deg_dec_digits + 2 >
WORK_SIZE)
356 lwerror(
"Bad format, degrees (DD.DDD) number of digits was greater than our working limit.");
360 snprintf(pieces[deg_piece],
WORK_SIZE,
"%*.*f", deg_digits, deg_dec_digits, degrees);
366 if (min_digits + min_dec_digits + 2 >
WORK_SIZE)
368 lwerror(
"Bad format, minutes (MM.MMM) number of digits was greater than our working limit.");
370 snprintf(pieces[min_piece],
WORK_SIZE,
"%*.*f", min_digits, min_dec_digits, minutes);
375 if (sec_digits + sec_dec_digits + 2 >
WORK_SIZE)
377 lwerror(
"Bad format, seconds (SS.SSS) number of digits was greater than our working limit.");
379 snprintf(pieces[sec_piece],
WORK_SIZE,
"%*.*f", sec_digits, sec_dec_digits, seconds);
387 strcpy(
result, pieces[0]);
390 strcat(
result, pieces[index]);
416 sz = strlen(lat_text) + strlen(lon_text) + 2;
418 snprintf(
result, sz,
"%s %s", lat_text, lon_text);
436 lwerror(
"Cannot convert a null point into formatted text.");
440 lwerror(
"Cannot convert an empty point into formatted text.");
465 length = d2sexp_buffered_n(d,
precision, buf);
469 length = d2sfixed_buffered_n(d,
precision, buf);
char result[OUT_DOUBLE_BUFFER_SIZE]
void * lwalloc(size_t size)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
static char * lwdouble_to_dms(double val, const char *pos_dir_symbol, const char *neg_dir_symbol, const char *format)
static char * lwdoubles_to_latlon(double lat, double lon, const char *format)
char * lwpoint_to_latlon(const LWPOINT *pt, const char *format)
static void lwprint_normalize_latlon(double *lat, double *lon)
int lwprint_double(double d, int maxdd, char *buf)