hello,
because doing it by hand or with already existing GRASS commands ist too
tedious, Elshad Shirinov programmed a small module for me which fullfills
this purpose.
The problem was, that coordinates which has been taken from a corner or center
of a sampling plot represent in fact a 50x50m or 50x200m plot/transect.
This module (r.buffer.rect) creates an area around the coordinate with defined
x and y side length and with defined position of the input coordinate.
e.g.: you sampled a 50x50m plot but you took the coordinate (x) of the
bottom-right corner, hence you need the actual area of your plot (1), that is
what r.buffer.rect does:
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 x
hope this module will help other people as well, Martin
P.S.: I will add it to the GRASS add-on Wiki in the near future, when we
setup the *.html manual page.
Usage:
r.buffer.rect input=string output=string keyval=value x=value y=value
alignment=string [title="phrase"] [--overwrite] [--verbose] [--quiet]
Flags:
--o Allow output files to overwrite existing files
--v Verbose module output
--q Quiet module output
Parameters:
input Name of existing raster file
output Name for the output raster file
keyval Value of relevant pixels in the input raster
x Width of the area
y Height of the area
alignment Alignment of the pixel relative to the rectangle
options: center,top-left,top-right,bottom-left,bottom-right
title Title of the output raster file
On Montag, 16. Juni 2008 16:18:49 Martin Wegmann wrote:
> Hello,
>
> I am looking for a way to create a square buffer for a point vector so that
> each point is in the end the centroid of a square with defined side length.
>
> I though about r.mapcalc statements to grow north-south and west-east and
> then somehow create an area from this square. But I have no idea how to do
> it without a lot of hand-work.
>
> Any idea how to achieve that? Or hints where to find relevant documents.
>
> Martin
>
> _______________________________________________
> grass-user mailing list
> [email protected]
> http://lists.osgeo.org/mailman/listinfo/grass-user
#include "local_proto.h"
/*
Creation of rectangular area around a point raster
by Elshad Shirinov.
*/
struct alignment
{
char *name; /* method name */
char *text; /* menu display - full description */
int index;
};
static struct alignment alignments[] =
{
{"center", "Key pixel will be the center of the buffer.", 0},
{"top-left", "Key pixel will be top-left of the buffer.", 1},
{"top-right", "Key pixel will be the top-right of the buffer.", 2},
{"bottom-left", "Key pixel will be the bottom-left of the buffer.", 3},
{"bottom-right", "Key pixel will be the bottom-right of the buffer.", 4},
{0,0,0}
};
int main (int argc, char *argv[])
{
/* input */
char *oldname, *oldmapset;
/* input */
char *newname, *newmapset;
/* in and out file pointers */
int in_fd;
int out_fd;
/* parameters */
int keyval;
int x, y;
int align;
int sx, sy;
/* maps */
CELL *map, *newmap;
/* other parameters */
char *title;
/* helper variables */
int row, col;
CELL *result;
char* str;
int n, i;
RASTER_MAP_TYPE map_type;
struct Cell_head ch, window;
struct GModule *module;
struct
{
struct Option *input, *output;
struct Option *keyval, *x, *y;
struct Option *alignment;
struct Option *title;
} parm;
G_gisinit (argv[0]);
module = G_define_module();
module->keywords = _("raster");
module->description =
_("Creates rectangular area around input point raster.");
parm.input = G_define_option() ;
parm.input->key = "input" ;
parm.input->type = TYPE_STRING ;
parm.input->required = YES ;
parm.input->gisprompt = "old,cell,raster" ;
parm.input->description= _("Name of existing raster file") ;
parm.output = G_define_option() ;
parm.output->key = "output" ;
parm.output->type = TYPE_STRING ;
parm.output->required = YES ;
parm.output->gisprompt = "new,cell,raster,output" ;
parm.output->description= _("Name for the output raster file") ;
parm.keyval = G_define_option() ;
parm.keyval->key = "keyval" ;
parm.keyval->type = TYPE_INTEGER ;
parm.keyval->required = YES ;
parm.keyval->description= _("Value of relevant pixels in the input raster") ;
parm.x = G_define_option() ;
parm.x->key = "x" ;
parm.x->type = TYPE_INTEGER ;
parm.x->required = YES ;
parm.x->description= _("Width of the area") ;
parm.y = G_define_option() ;
parm.y->key = "y" ;
parm.y->type = TYPE_INTEGER ;
parm.y->required = YES ;
parm.y->description= _("Height of the area") ;
parm.alignment = G_define_option() ;
parm.alignment->key = "alignment" ;
parm.alignment->type = TYPE_STRING ;
parm.alignment->required = YES ;
str = parm.alignment->options = G_malloc(1024);
for (n = 0; alignments[n].name; n++)
{
if (n)
strcat (str, ",");
else
*str = 0;
strcat (str, alignments[n].name);
}
parm.alignment->description= _("Alignment of the key pixel relative to the new rectangular area") ;
parm.title = G_define_option() ;
parm.title->key = "title" ;
parm.title->key_desc = "\"phrase\"" ;
parm.title->type = TYPE_STRING ;
parm.title->required = NO ;
parm.title->description= _("Title of the output raster file") ;
if (G_parser(argc,argv))
exit(EXIT_FAILURE);
/* get name of input file */
oldname = parm.input->answer;
/* test input files existence */
if( (oldmapset = G_find_cell2(oldname,"")) == NULL )
{
G_warning ( _("%s: <%s> raster file not found\n"), G_program_name(), oldname);
G_usage();
exit(EXIT_FAILURE);
}
/* check if the new file name is correct */
newname = parm.output->answer;
if (G_legal_filename(newname) < 0)
{
G_warning("%s: <%s> illegal file name\n", G_program_name(), newname);
exit(EXIT_FAILURE);
}
newmapset = G_mapset();
/* read keyval */
sscanf(parm.keyval->answer, "%d", &keyval);
/* read x */
sscanf(parm.x->answer, "%d", &x);
/* read y */
sscanf(parm.y->answer, "%d", &y);
/* align with input */
if (G_get_cellhd(oldname, oldmapset, &ch) < 0) {
G_fatal_error ( _("Couldn't read CELL_HEAD structure from file <%s> in mapset <%s>\n"),
oldname, oldmapset);
exit(EXIT_FAILURE);
}
G_get_window(&window);
G_align_window(&window, &ch);
G_set_window(&window);
/* get size */
sx = G_window_cols();
sy = G_window_rows();
/* find alignment */
for (n = 0; (str = alignments[n].name); n++)
if (strcmp(str, parm.alignment->answer) == 0)
break;
if (str) {
align = alignments[n].index;
} else {
G_warning (_("<%s=%s> unknown %s"),
parm.alignment->key, parm.alignment->answer, parm.alignment->key);
G_usage();
exit(EXIT_FAILURE);
}
/* allocate map buffers */
map = (CELL*) G_malloc (sx * sy * sizeof(CELL));
newmap = (CELL*) G_malloc(sx * sy * sizeof(CELL));
result = G_allocate_c_raster_buf();
/* fill newmap with null */
G_set_c_null_value(newmap, sx * sy);
/* open map */
if ((in_fd = G_open_cell_old (oldname, oldmapset)) < 0)
{
G_fatal_error ( _("can't open cell file <%s> in mapset %s\n"), oldname, oldmapset);
G_usage();
exit(EXIT_FAILURE);
}
/* read map */
G_message("Reading map file:\n");
for (row = 0; row < sy; row++) {
G_get_c_raster_row (in_fd, map + row * sx, row);
G_percent (row + 1, sy, 1);
}
/* create buffers */
for(row = 0; row < sy; row++) {
for(col = 0; col < sx; col++) {
if(map[row * sx + col] == keyval) {
set_buffer(newmap, col, row, x, y, sx, sy, align);
}
}
}
/* close map */
G_close_cell(in_fd);
/* write the output file */
G_message("Writing output ... ");
/* open cell file */
if ((in_fd = G_open_cell_old (oldname, oldmapset)) < 0)
{
}
/* open new cell file */
out_fd = G_open_raster_new (newname, CELL_TYPE);
if (out_fd < 0) {
G_fatal_error("Can't create new cell file <%s> in mapset %s", newname, newmapset);
exit(EXIT_FAILURE);
}
/* write output */
for(row = 0; row < sy; row++) {
G_set_c_null_value(result, sx);
for(col = 0; col < sx; col++) {
result[col] = newmap[row * sx + col];
}
G_put_c_raster_row(out_fd, result);
G_percent (row + 1, sy, 1);
}
/* close new file */
G_close_cell(out_fd);
/* free allocated resources */
G_free(map);
G_free(newmap);
G_free(result);
exit(EXIT_SUCCESS);
}
MODULE_TOPDIR = ../..
PGM = r.buffer.rect
LIBES = $(STATSLIB) $(GISLIB)
DEPENDENCIES = $(STATSDEP) $(GISDEP)
include $(MODULE_TOPDIR)/include/Make/Module.make
default: cmd
#include "local_proto.h"
void set_buffer(CELL* buffer, int x, int y, int width, int height, int sx, int sy, int align) {
int l, r, t, b;
int i, j;
int dx, dy;
switch(align) {
case 0: /* center */
dx = width / 2;
dy = height / 2;
l = x - dx;
r = x + dx;
t = y - dy;
b = y + dy;
break;
case 1: /* top-left */
l = x;
r = x + width - 1;
t = y;
b = y + height - 1;
break;
case 2: /* top-right */
l = x - width + 1;
r = x;
t = y;
b = y + height - 1;
break;
case 3: /* bottom-left */
l = x;
r = x + width - 1;
t = y - height + 1;
b = y;
break;
case 4: /* bottom-right */
l = x - width + 1;
r = x;
t = y - height + 1;
b = y;
break;
default:
l = t = 0;
r = b = 1;
break;
}
l = l < 0 ? 0 : l;
r = r >= sx ? sx - 1 : r;
t = t < 0 ? 0 : t;
b = b >= sy ? sy - 1 : b;
/* fill buffer */
for(j = t; j <= b; j++) {
for(i = l; i <= r; i++) {
buffer[j * sx + i] = 1;
}
}
}
#ifndef LOCAL_PROTO_H
#define LOCAL_PROTO_H
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <grass/gis.h>
#include <grass/glocale.h>
#include <grass/stats.h>
#include <math.h>
#include <time.h>
/* buffer.c */
void set_buffer(CELL* buffer, int x, int y, int width, int height, int sx, int sy, int align);
#endif /* LOCAL_PROTO_H */
_______________________________________________
grass-user mailing list
[email protected]
http://lists.osgeo.org/mailman/listinfo/grass-user