123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- /****************************************************************************
- *
- * MODULE: r.distance
- *
- * AUTHOR(S): Michael Shapiro - CERL
- * Sort/reverse sort by distance by Huidae Cho
- *
- * PURPOSE: Locates the closest points between objects in two
- * raster maps.
- *
- * COPYRIGHT: (C) 2003-2014 by the GRASS Development Team
- *
- * This program is free software under the GNU General
- * Public License (>=v2). Read the file COPYING that
- * comes with GRASS for details.
- *
- ***************************************************************************/
- #include <stdlib.h>
- #include <grass/glocale.h>
- #include "defs.h"
- struct ReportLine
- {
- CELL cat1;
- CELL cat2;
- int isnull1;
- int isnull2;
- double east1;
- double north1;
- double east2;
- double north2;
- double distance;
- };
- static void print(struct ReportLine *, struct Parms *);
- static int compare(const void *, const void *);
- static int revcompare(const void *, const void *);
- void report(struct Parms *parms)
- {
- int i1, i2;
- struct Map *map1, *map2;
- double distance, north1, east1, north2, east2;
- struct Cell_head region;
- struct CatEdgeList *list1, *list2;
- struct ReportLine *lines;
- int nlines;
- extern void find_minimum_distance();
- extern char *get_label();
- G_get_set_window(®ion);
- G_begin_distance_calculations();
- map1 = &parms->map1;
- map2 = &parms->map2;
- G_message(_("Processing..."));
- if (parms->sort > 0)
- lines = (struct ReportLine *)G_malloc(
- map1->edges.ncats * map2->edges.ncats *
- sizeof(struct ReportLine));
- else
- lines = NULL;
- nlines = 0;
- for (i1 = 0; i1 < map1->edges.ncats; i1++) {
- int isnull1;
- list1 = &map1->edges.catlist[i1];
- isnull1 = parms->null ? Rast_is_c_null_value(&(list1->cat)) : 0;
- for (i2 = 0; i2 < map2->edges.ncats; i2++) {
- int isnull2;
- struct ReportLine line;
- list2 = &map2->edges.catlist[i2];
- isnull2 = parms->null ? Rast_is_c_null_value(&(list2->cat)) : 0;
- find_minimum_distance(list1, list2,
- &east1, &north1, &east2, &north2, &distance,
- ®ion, parms->overlap, map1->name,
- map2->name);
- line.cat1 = list1->cat;
- line.cat2 = list2->cat;
- line.isnull1 = isnull1;
- line.isnull2 = isnull2;
- line.east1 = east1;
- line.north1 = north1;
- line.east2 = east2;
- line.north2 = north2;
- line.distance = distance;
- if (parms->sort > 0)
- lines[nlines++] = line;
- else
- print(&line, parms);
- }
- }
- if (parms->sort > 0) {
- int i;
- if (parms->sort == 1)
- qsort(lines, nlines, sizeof(struct ReportLine), compare);
- else
- qsort(lines, nlines, sizeof(struct ReportLine), revcompare);
- for(i = 0; i < nlines; i++)
- print(&lines[i], parms);
- }
- }
- static void print(struct ReportLine *line, struct Parms *parms)
- {
- char *fs;
- char temp[100];
- fs = parms->fs;
- /* print cat numbers */
- if (line->isnull1 && line->isnull2)
- fprintf(stdout, "*%s*", fs);
- else if (line->isnull1)
- fprintf(stdout, "*%s%ld", fs, (long)line->cat2);
- else if (line->isnull2)
- fprintf(stdout, "%ld%s*", (long)line->cat1, fs);
- else
- fprintf(stdout, "%ld%s%ld", (long)line->cat1, fs, (long)line->cat2);
- /* print distance */
- sprintf(temp, "%.10f", line->distance);
- G_trim_decimal(temp);
- fprintf(stdout, "%s%s", fs, temp);
- /* print coordinates of the closest pair */
- G_format_easting(line->east1, temp,
- G_projection() == PROJECTION_LL ? -1 : 0);
- fprintf(stdout, "%s%s", fs, temp);
- G_format_northing(line->north1, temp,
- G_projection() == PROJECTION_LL ? -1 : 0);
- fprintf(stdout, "%s%s", fs, temp);
- G_format_easting(line->east2, temp,
- G_projection() == PROJECTION_LL ? -1 : 0);
- fprintf(stdout, "%s%s", fs, temp);
- G_format_northing(line->north2, temp,
- G_projection() == PROJECTION_LL ? -1 : 0);
- fprintf(stdout, "%s%s", fs, temp);
- /* print category labels */
- if (parms->labels) {
- struct Map *map1, *map2;
- map1 = &parms->map1;
- map2 = &parms->map2;
- fprintf(stdout, "%s%s", fs, get_label(map1, line->cat1));
- fprintf(stdout, "%s%s", fs, get_label(map2, line->cat2));
- }
- fprintf(stdout, "\n");
- }
- static int compare(const void *p1, const void *p2)
- {
- const struct ReportLine *line1, *line2;
- line1 = (const struct ReportLine *)p1;
- line2 = (const struct ReportLine *)p2;
- if (line1->distance < line2->distance) return -1; /* short distance first */
- if (line1->distance > line2->distance) return 1;
- if (!line1->isnull1 && line2->isnull1) return -1; /* non-null first */
- if (line1->isnull1 && !line2->isnull1) return 1;
- if (!line1->isnull1 && !line2->isnull1) {
- if (line1->cat1 < line2->cat1) return -1; /* small cat first */
- if (line1->cat1 > line2->cat1) return 1;
- }
- if (!line1->isnull2 && line2->isnull2) return -1;
- if (line1->isnull2 && !line2->isnull2) return 1;
- if (!line1->isnull2 && !line2->isnull2) {
- if (line1->cat2 < line2->cat2) return -1;
- if (line1->cat2 > line2->cat2) return 1;
- }
- return 0; /* same cat1, same cat2 */
- }
- static int revcompare(const void *p1, const void *p2)
- {
- return -compare(p1, p2);
- }
|