[GRASS-SVN] r60563 - grass/trunk/raster/r.distance
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed May 28 14:09:09 PDT 2014
Author: hcho
Date: 2014-05-28 14:09:09 -0700 (Wed, 28 May 2014)
New Revision: 60563
Modified:
grass/trunk/raster/r.distance/defs.h
grass/trunk/raster/r.distance/main.c
grass/trunk/raster/r.distance/parse.c
grass/trunk/raster/r.distance/report.c
Log:
r.distance: -s/-r sort by distance implemented
Modified: grass/trunk/raster/r.distance/defs.h
===================================================================
--- grass/trunk/raster/r.distance/defs.h 2014-05-28 21:00:04 UTC (rev 60562)
+++ grass/trunk/raster/r.distance/defs.h 2014-05-28 21:09:09 UTC (rev 60563)
@@ -52,6 +52,9 @@
char *fs; /* report field separator */
int overlap; /* checking for overlapping, than distance is 0 */
int null; /* report null objects as * */
+ int sort; /* 0: sort by cat1,cat2 (default)
+ 1: sort by distance in ascending order
+ 2: sort by distance in descending order */
};
/* distance.c */
Modified: grass/trunk/raster/r.distance/main.c
===================================================================
--- grass/trunk/raster/r.distance/main.c 2014-05-28 21:00:04 UTC (rev 60562)
+++ grass/trunk/raster/r.distance/main.c 2014-05-28 21:09:09 UTC (rev 60563)
@@ -4,11 +4,12 @@
* 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, 2012 by the GRASS Development Team
+ * 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
Modified: grass/trunk/raster/r.distance/parse.c
===================================================================
--- grass/trunk/raster/r.distance/parse.c 2014-05-28 21:00:04 UTC (rev 60562)
+++ grass/trunk/raster/r.distance/parse.c 2014-05-28 21:09:09 UTC (rev 60563)
@@ -25,7 +25,7 @@
void parse(int argc, char *argv[], struct Parms *parms)
{
struct Option *maps, *fs;
- struct Flag *labels, *overlap, *null;
+ struct Flag *labels, *overlap, *null, *sort, *revsort;
const char *name, *mapset;
maps = G_define_standard_option(G_OPT_R_MAPS);
@@ -48,9 +48,21 @@
null->key = 'n';
null->description = _("Report null objects as *");
+ sort = G_define_flag();
+ sort->key = 's';
+ sort->description = _("Sort by distance in ascending order");
+
+ revsort = G_define_flag();
+ revsort->key = 'r';
+ revsort->description = _("Sort by distance in descending order");
+
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
+ if (sort->answer && revsort->answer)
+ G_fatal_error(_("-%c and -%c are mutually exclusive"),
+ sort->key, revsort->key);
+
name = parms->map1.name = maps->answers[0];
mapset = parms->map1.mapset = G_find_raster2(name, "");
if (mapset == NULL)
@@ -73,4 +85,5 @@
parms->fs = fs->answer;
parms->overlap = overlap->answer ? 1 : 0;
parms->null = null->answer ? 1 : 0;
+ parms->sort = sort->answer ? 1 : (revsort->answer ? 2 : 0);
}
Modified: grass/trunk/raster/r.distance/report.c
===================================================================
--- grass/trunk/raster/r.distance/report.c 2014-05-28 21:00:04 UTC (rev 60562)
+++ grass/trunk/raster/r.distance/report.c 2014-05-28 21:09:09 UTC (rev 60563)
@@ -16,19 +16,37 @@
*
***************************************************************************/
+#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;
- char *fs;
double distance, north1, east1, north2, east2;
struct Cell_head region;
struct CatEdgeList *list1, *list2;
- char temp[100];
+ struct ReportLine *lines;
+ int nlines;
extern void find_minimum_distance();
extern char *get_label();
@@ -38,10 +56,17 @@
map1 = &parms->map1;
map2 = &parms->map2;
- fs = parms->fs;
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;
@@ -50,6 +75,7 @@
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;
@@ -59,42 +85,113 @@
®ion, parms->overlap, map1->name,
map2->name);
- /* print cat numbers */
- if (isnull1 && isnull2)
- fprintf(stdout, "*%s*", fs);
- else if (isnull1)
- fprintf(stdout, "*%s%ld", fs, (long)list2->cat);
- else if (isnull2)
- fprintf(stdout, "%ld%s*", (long)list1->cat, fs);
+ 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
- fprintf(stdout, "%ld%s%ld", (long)list1->cat, fs,
- (long)list2->cat);
+ print(&line, parms);
+ }
+ }
- /* print distance */
- sprintf(temp, "%.10f", distance);
- G_trim_decimal(temp);
- fprintf(stdout, "%s%s", fs, temp);
+ if (parms->sort > 0) {
+ int i;
- /* print coordinates of the closest pair */
- G_format_easting(east1, temp,
- G_projection() == PROJECTION_LL ? -1 : 0);
- fprintf(stdout, "%s%s", fs, temp);
- G_format_northing(north1, temp,
- G_projection() == PROJECTION_LL ? -1 : 0);
- fprintf(stdout, "%s%s", fs, temp);
- G_format_easting(east2, temp,
- G_projection() == PROJECTION_LL ? -1 : 0);
- fprintf(stdout, "%s%s", fs, temp);
- G_format_northing(north2, temp,
- G_projection() == PROJECTION_LL ? -1 : 0);
- fprintf(stdout, "%s%s", fs, temp);
+ if (parms->sort == 1)
+ qsort(lines, nlines, sizeof(struct ReportLine), compare);
+ else
+ qsort(lines, nlines, sizeof(struct ReportLine), revcompare);
- /* print category labels */
- if (parms->labels) {
- fprintf(stdout, "%s%s", fs, get_label(map1, list1->cat));
- fprintf(stdout, "%s%s", fs, get_label(map2, list2->cat));
- }
- fprintf(stdout, "\n");
- }
+ 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);
+}
More information about the grass-commit
mailing list