parse_dist.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /****************************************************************************
  2. *
  3. * MODULE: r.buffer
  4. *
  5. * AUTHOR(S): Michael Shapiro - CERL
  6. *
  7. * PURPOSE: This program creates distance zones from non-zero
  8. * cells in a grid layer. Distances are specified in
  9. * meters (on the command-line). Window does not have to
  10. * have square cells. Works both for planimetric
  11. * (UTM, State Plane) and lat-long.
  12. *
  13. * COPYRIGHT: (C) 2005 by the GRASS Development Team
  14. *
  15. * This program is free software under the GNU General Public
  16. * License (>=v2). Read the file COPYING that comes with GRASS
  17. * for details.
  18. *
  19. ****************************************************************************/
  20. #include <stdlib.h>
  21. #include "distance.h"
  22. #include <grass/glocale.h>
  23. static int cmp(const void *, const void *);
  24. static int scan_dist(char *, double *);
  25. int parse_distances(char **zone_list, double to_meters)
  26. {
  27. double dist;
  28. double ew2 = 0.0;
  29. int i;
  30. int count;
  31. for (count = 0; zone_list[count]; count++) ;
  32. if (count <= 0)
  33. return 0;
  34. /* create an array to hold the distances */
  35. distances = (struct Distance *)G_calloc(count, sizeof(struct Distance));
  36. /* scan the command line for the distances */
  37. if (window.proj != PROJECTION_LL) {
  38. ew2 = window.ew_res * window.ew_res;
  39. ns_to_ew_squared = window.ns_res * window.ns_res / ew2;
  40. }
  41. for (i = 0; i < count; i++) {
  42. if (!scan_dist(zone_list[i], &dist)) {
  43. G_warning(_("%s: %s - illegal distance specification"),
  44. pgm_name, zone_list[i]);
  45. return 0;
  46. }
  47. else {
  48. dist *= (to_meters * meters_to_grid);
  49. if (window.proj != PROJECTION_LL)
  50. dist = dist * dist / ew2;
  51. distances[i].dist = dist;
  52. }
  53. distances[i].label = zone_list[i];
  54. }
  55. /* sort the distances in increasing order */
  56. qsort(distances, count, sizeof(struct Distance), cmp);
  57. return count;
  58. }
  59. static int cmp(const void *aa, const void *bb)
  60. {
  61. const struct Distance *a = aa, *b = bb;
  62. if (a->dist < b->dist)
  63. return -1;
  64. return a->dist > b->dist;
  65. }
  66. static int scan_dist(char *s, double *dist)
  67. {
  68. char dummy[2];
  69. *dummy = 0;
  70. if (sscanf(s, "%lf%1s", dist, dummy) != 1)
  71. return 0;
  72. if (*dummy)
  73. return 0;
  74. if (*dist <= 0.0)
  75. return 0;
  76. return 1;
  77. }