-> hdddmmss (hemisphere-degrees-minutes-seconds) -> hddd.dddddd (hemisphere-degrees.decimal degrees) -> +-ddd.dddddd (hemisphere[+/-]-degrees.decimal degrees) (“+” for N and E, “-“ for S and W; the plus sign is optional) -> hdddmm.mmmm (hemisphere-degrees-minutes.decimal minutes): -> hdddmmss.sss (hemisphere-degrees-minutes-seconds.decimal seconds)
degrees/minutes/seconds: hdddmmss (hemisphere-degrees-minutes-seconds) Ex. 0793235 +0793235 E0793235 || | |-> seconds (2 digits; left padded with 0) || |-> minutes (2 digits; left padded with 0) ||-> degrees (3 digits; left padded with 0) |-> start_literal (1 digit; optional)
decimal degrees: hddd.dddddd (hemisphere-degrees.decimal degrees) Ex. E079.533265 +079.533265 || |-> indicates decimal degrees ||-> degrees (3 digits; left padded with 0) |-> start_literal (1 digit; optional)
decimal minutes: hdddmm.mmmm (cardinal direction|degrees|minutes.decimal minutes) Ex. E07932.5332 || | |-> indicates decimal minutes || |-> minutes (2 digits; left padded with 0) ||-> degrees (3 digits; left padded with 0) |-> start_literal (1 digit; optional)
decimal seconds: hdddmmss.sss (hemisphere-degrees-minutes-seconds.decimal seconds) Ex. E0793235.575 || | | |-> indicates decimal seconds || | |-> seconds (2 digits; left padded with 0) || |-> minutes (2 digits; left padded with 0) ||-> degrees (3 digits; left padded with 0) |-> start_literal (1 digit; optional)
188 size_t literal_length;
190 char start_character = literal[0];
191 int start_literal = 0;
194 const size_t numdigits_degrees = 3;
195 const size_t numdigits_minutes = 2;
196 const size_t numdigits_seconds = 2;
198 POSTGIS_DEBUGF(2,
"parse_geo_literal called (%s)", literal);
199 POSTGIS_DEBUGF(2,
" start character: %c", start_character);
201 literal_length = strlen(literal);
203 if (!isdigit(start_character)) start_literal = 1;
205 POSTGIS_DEBUGF(2,
" start_literal=%d", start_literal);
207 dgr = palloc(
sizeof(
char)*numdigits_degrees+1);
208 snprintf(dgr, numdigits_degrees+1,
"%s", &literal[start_literal]);
210 if (strchr(literal,
'.') == NULL && strchr(literal,
',') == NULL) {
223 POSTGIS_DEBUG(2,
" lat/lon integer coordinates detected");
224 POSTGIS_DEBUGF(2,
" parsed degrees (lon/lat): %s", dgr);
231 if (literal_length > (start_literal + numdigits_degrees)) {
233 min = palloc(
sizeof(
char)*numdigits_minutes+1);
234 snprintf(min, numdigits_minutes+1,
"%s", &literal[start_literal+numdigits_degrees]);
235 POSTGIS_DEBUGF(2,
" parsed minutes (lon/lat): %s", min);
240 if (literal_length >= (start_literal + numdigits_degrees + numdigits_minutes)) {
242 sec = palloc(
sizeof(
char)*numdigits_seconds+1);
243 snprintf(sec, numdigits_seconds+1,
"%s", &literal[start_literal+numdigits_degrees+numdigits_minutes]);
244 POSTGIS_DEBUGF(2,
" parsed seconds (lon/lat): %s", sec);
257 POSTGIS_DEBUG(2,
" decimal coordinates detected");
259 if (strchr(literal,
',')) {
264 literal[literal_length-strlen(strchr(literal,
','))]=
'.';
265 POSTGIS_DEBUGF(2,
" decimal separator changed to '.': %s",literal);
270 if (literal[start_literal + numdigits_degrees] ==
'.') {
281 char *dec = palloc(
sizeof(
char)*literal_length+1);
282 snprintf(dec, literal_length+1,
"%s", &literal[start_literal]);
285 POSTGIS_DEBUGF(2,
" parsed decimal degrees: %s", dec);
289 }
else if (literal[start_literal + numdigits_degrees + numdigits_minutes] ==
'.') {
300 size_t len_decimal_minutes = literal_length - (start_literal + numdigits_degrees);
302 min = palloc(
sizeof(
char)*len_decimal_minutes+1);
303 snprintf(min, len_decimal_minutes+1,
"%s", &literal[start_literal + numdigits_degrees]);
305 POSTGIS_DEBUGF(2,
" parsed degrees: %s", dgr);
306 POSTGIS_DEBUGF(2,
" parsed decimal minutes: %s", min);
308 result = atof(dgr) + (atof(min) / 60);
313 }
else if (literal[start_literal + numdigits_degrees + numdigits_minutes + numdigits_seconds] ==
'.') {
325 size_t len_decimal_seconds = literal_length - (start_literal + numdigits_degrees + numdigits_minutes);
327 min = palloc(
sizeof(
char)*numdigits_minutes+1);
328 snprintf(min, numdigits_minutes+1,
"%s", &literal[start_literal + numdigits_degrees]);
330 sec = palloc(
sizeof(
char)*len_decimal_seconds+1);
331 snprintf(sec, len_decimal_seconds+1,
"%s", &literal[start_literal + numdigits_degrees + numdigits_minutes]);
333 result = atof(dgr) + (atof(min) / 60) + (atof(sec) / 3600);
335 POSTGIS_DEBUGF(2,
" parsed degrees: %s", dgr);
336 POSTGIS_DEBUGF(2,
" parsed minutes: %s", min);
337 POSTGIS_DEBUGF(2,
" parsed decimal seconds: %s", sec);
352 if (start_character ==
'S' || start_character ==
'W' || start_character ==
'-') {
354 POSTGIS_DEBUGF(2,
" switching sign due to start character: '%c'", start_character);
359 POSTGIS_DEBUGF(2,
"=> parse_geo_literal returns: %.*f (in decimal degrees)", literal_length-(3+start_literal),
result);
char result[OUT_DOUBLE_BUFFER_SIZE]