parse_dist.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. ;
  33. if (count <= 0) 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. {
  39. ew2 = window.ew_res * window.ew_res;
  40. ns_to_ew_squared = window.ns_res * window.ns_res / ew2;
  41. }
  42. for (i = 0; i < count; i++)
  43. {
  44. if (!scan_dist(zone_list[i], &dist))
  45. {
  46. G_warning(_("%s: %s - illegal distance specification"),
  47. pgm_name, zone_list[i]);
  48. return 0;
  49. }
  50. else
  51. {
  52. dist *= (to_meters * meters_to_grid);
  53. if (window.proj != PROJECTION_LL)
  54. dist = dist*dist/ew2;
  55. distances[i].dist = dist;
  56. }
  57. distances[i].label = zone_list[i];
  58. }
  59. /* sort the distances in increasing order */
  60. qsort (distances, count, sizeof(struct Distance), cmp);
  61. return count;
  62. }
  63. static int cmp (const void *aa, const void *bb)
  64. {
  65. const struct Distance *a = aa, *b = bb;
  66. if (a->dist < b->dist) return -1;
  67. return a->dist > b->dist;
  68. }
  69. static int scan_dist (char *s, double *dist)
  70. {
  71. char dummy[2];
  72. *dummy = 0;
  73. if (sscanf (s, "%lf%1s", dist, dummy) != 1) return 0;
  74. if (*dummy) return 0;
  75. if (*dist <= 0.0) return 0;
  76. return 1;
  77. }