distance.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /****************************************************************************
  2. *
  3. * MODULE: r.distance
  4. *
  5. * AUTHOR(S): Michael Shapiro - CERL
  6. *
  7. * PURPOSE: Locates the closest points between objects in two
  8. * raster maps.
  9. *
  10. * COPYRIGHT: (C) 2003 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. ***************************************************************************/
  17. #include <grass/raster.h>
  18. #include <grass/glocale.h>
  19. #include "defs.h"
  20. /* given two CatEdgeLists, find the cells which are closest
  21. * and return east,north for the tow cells and the distance between them
  22. */
  23. /* this code assumes that list1 and list2 have at least one cell in each */
  24. void
  25. find_minimum_distance(const struct CatEdgeList *list1, const struct CatEdgeList *list2,
  26. double *east1, double *north1, double *east2, double *north2,
  27. double *distance, const struct Cell_head *region, int overlap,
  28. const char *name1, const char *name2)
  29. {
  30. int i1, i2;
  31. double dist;
  32. double e1, n1, e2, n2;
  33. extern double G_distance();
  34. extern double Rast_row_to_northing();
  35. extern double Rast_col_to_easting();
  36. int zerro_row, zerro_col;
  37. int nulldistance = 0;
  38. if (overlap)
  39. nulldistance = null_distance(name1, name2, &zerro_row, &zerro_col);
  40. for (i1 = 0; i1 < list1->ncells; i1++) {
  41. e1 = Rast_col_to_easting(list1->col[i1] + 0.5, region);
  42. n1 = Rast_row_to_northing(list1->row[i1] + 0.5, region);
  43. for (i2 = 0; i2 < list2->ncells; i2++) {
  44. if (!nulldistance) {
  45. e2 = Rast_col_to_easting(list2->col[i2] + 0.5, region);
  46. n2 = Rast_row_to_northing(list2->row[i2] + 0.5, region);
  47. dist = G_distance(e1, n1, e2, n2);
  48. }
  49. else {
  50. e2 = e1 = Rast_col_to_easting(zerro_col + 0.5, region);
  51. n2 = n1 = Rast_row_to_northing(zerro_row + 0.5, region);
  52. dist = 0.;
  53. }
  54. if ((i1 == 0 && i2 == 0) || (dist < *distance)) {
  55. *distance = dist;
  56. *east1 = e1;
  57. *north1 = n1;
  58. *east2 = e2;
  59. *north2 = n2;
  60. }
  61. if (nulldistance)
  62. break;
  63. }
  64. if (nulldistance)
  65. break;
  66. }
  67. }
  68. int null_distance(const char *name1, const char *name2, int *zerro_row, int *zerro_col)
  69. {
  70. RASTER_MAP_TYPE maptype1, maptype2;
  71. const char *mapset;
  72. int mapd1, mapd2;
  73. void *inrast1, *inrast2;
  74. int nrows, ncols, row, col;
  75. void *cell1, *cell2;
  76. /* NOTE: no need to controll, if the map exists. it should be checked in edge.c */
  77. mapset = G_find_raster2(name1, "");
  78. maptype1 = Rast_map_type(name1, mapset);
  79. mapd1 = Rast_open_old(name1, mapset);
  80. inrast1 = Rast_allocate_buf(maptype1);
  81. mapset = G_find_raster2(name2, "");
  82. maptype2 = Rast_map_type(name2, mapset);
  83. mapd2 = Rast_open_old(name2, mapset);
  84. inrast2 = Rast_allocate_buf(maptype2);
  85. G_message(_("Reading maps <%s,%s> while finding 0 distance ..."), name1,
  86. name2);
  87. ncols = Rast_window_cols();
  88. nrows = Rast_window_rows();
  89. for (row = 0; row < nrows; row++) {
  90. G_percent(row, nrows, 2);
  91. Rast_get_row(mapd1, inrast1, row, maptype1);
  92. Rast_get_row(mapd2, inrast2, row, maptype2);
  93. for (col = 0; col < ncols; col++) {
  94. /* first raster */
  95. switch (maptype1) {
  96. case CELL_TYPE:
  97. cell1 = ((CELL **) inrast1)[col];
  98. break;
  99. case FCELL_TYPE:
  100. cell1 = ((FCELL **) inrast1)[col];
  101. break;
  102. case DCELL_TYPE:
  103. cell1 = ((DCELL **) inrast1)[col];
  104. break;
  105. }
  106. /* second raster */
  107. switch (maptype2) {
  108. case CELL_TYPE:
  109. cell2 = ((CELL **) inrast2)[col];
  110. break;
  111. case FCELL_TYPE:
  112. cell2 = ((FCELL **) inrast2)[col];
  113. break;
  114. case DCELL_TYPE:
  115. cell2 = ((DCELL **) inrast2)[col];
  116. break;
  117. }
  118. if (!Rast_is_null_value(&cell1, maptype1) &&
  119. !Rast_is_null_value(&cell2, maptype2)) {
  120. *zerro_row = row;
  121. *zerro_col = col;
  122. /* memory cleanup */
  123. G_free(inrast1);
  124. G_free(inrast2);
  125. /* closing raster maps */
  126. Rast_close(mapd1);
  127. Rast_close(mapd2);
  128. return 1;
  129. }
  130. }
  131. }
  132. /* memory cleanup */
  133. G_free(inrast1);
  134. G_free(inrast2);
  135. /* closing raster maps */
  136. Rast_close(mapd1);
  137. Rast_close(mapd2);
  138. return 0;
  139. }