-> 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)
192 {
193
206 char *dgr;
207 char *min;
208 char *sec;
209 size_t literal_length;
210
211 char start_character = literal[0];
212 int start_literal = 0;
214
215 const size_t numdigits_degrees = 3;
216 const size_t numdigits_minutes = 2;
217 const size_t numdigits_seconds = 2;
218
219 POSTGIS_DEBUGF(2, "parse_geo_literal called (%s)", literal);
220 POSTGIS_DEBUGF(2, " start character: %c", start_character);
221
222 literal_length = strlen(literal);
223
224 if (!isdigit(start_character)) start_literal = 1;
225
226 POSTGIS_DEBUGF(2, " start_literal=%d", start_literal);
227
228 dgr = palloc(sizeof(char)*numdigits_degrees+1);
229 snprintf(dgr, numdigits_degrees+1, "%s", &literal[start_literal]);
230
231 if (strchr(literal, '.') == NULL && strchr(literal, ',') == NULL) {
232
244 POSTGIS_DEBUG(2, " lat/lon integer coordinates detected");
245 POSTGIS_DEBUGF(2, " parsed degrees (lon/lat): %s", dgr);
246
247
248
250
251
252 if (literal_length > (start_literal + numdigits_degrees)) {
253
254 min = palloc(sizeof(char)*numdigits_minutes+1);
255 snprintf(min, numdigits_minutes+1, "%s", &literal[start_literal+numdigits_degrees]);
256 POSTGIS_DEBUGF(2, " parsed minutes (lon/lat): %s", min);
258 pfree(min);
259
260
261 if (literal_length >= (start_literal + numdigits_degrees + numdigits_minutes)) {
262
263 sec = palloc(sizeof(char)*numdigits_seconds+1);
264 snprintf(sec, numdigits_seconds+1, "%s", &literal[start_literal+numdigits_degrees+numdigits_minutes]);
265 POSTGIS_DEBUGF(2, " parsed seconds (lon/lat): %s", sec);
266
268 pfree(sec);
269
270 }
271
272
273 }
274
275
276 } else {
277
278 POSTGIS_DEBUG(2, " decimal coordinates detected");
279
280 if (strchr(literal, ',')) {
281
282
283
284
285 literal[literal_length-strlen(strchr(literal, ','))]='.';
286 POSTGIS_DEBUGF(2, " decimal separator changed to '.': %s",literal);
287
288 }
289
290
291 if (literal[start_literal + numdigits_degrees] == '.') {
292
302 char *dec = palloc(sizeof(char)*literal_length+1);
303 snprintf(dec, literal_length+1, "%s", &literal[start_literal]);
305
306 POSTGIS_DEBUGF(2, " parsed decimal degrees: %s", dec);
307 pfree(dec);
308
309
310 } else if (literal[start_literal + numdigits_degrees + numdigits_minutes] == '.') {
311
321 size_t len_decimal_minutes = literal_length - (start_literal + numdigits_degrees);
322
323 min = palloc(sizeof(char)*len_decimal_minutes+1);
324 snprintf(min, len_decimal_minutes+1, "%s", &literal[start_literal + numdigits_degrees]);
325
326 POSTGIS_DEBUGF(2, " parsed degrees: %s", dgr);
327 POSTGIS_DEBUGF(2, " parsed decimal minutes: %s", min);
328
329 result = atof(dgr) + (atof(min) / 60);
330
331 pfree(min);
332
333
334 } else if (literal[start_literal + numdigits_degrees + numdigits_minutes + numdigits_seconds] == '.') {
335
346 size_t len_decimal_seconds = literal_length - (start_literal + numdigits_degrees + numdigits_minutes);
347
348 min = palloc(sizeof(char)*numdigits_minutes+1);
349 snprintf(min, numdigits_minutes+1, "%s", &literal[start_literal + numdigits_degrees]);
350
351 sec = palloc(sizeof(char)*len_decimal_seconds+1);
352 snprintf(sec, len_decimal_seconds+1, "%s", &literal[start_literal + numdigits_degrees + numdigits_minutes]);
353
354 result = atof(dgr) + (atof(min) / 60) + (atof(sec) / 3600);
355
356 POSTGIS_DEBUGF(2, " parsed degrees: %s", dgr);
357 POSTGIS_DEBUGF(2, " parsed minutes: %s", min);
358 POSTGIS_DEBUGF(2, " parsed decimal seconds: %s", sec);
359 pfree(min);
360 pfree(sec);
361
362 }
363
364 }
365
371 pfree(dgr);
372
373 if (start_character == 'S' || start_character == 'W' || start_character == '-') {
374
375 POSTGIS_DEBUGF(2, " switching sign due to start character: '%c'", start_character);
377
378 }
379
381}
char result[OUT_DOUBLE_BUFFER_SIZE]