[GRASS-dev] [bug #4469] (grass) g.region: nsres & ewres are rounded differently

this bug's URL: http://intevation.de/rt/webrt?serial_num=4469
-------------------------------------------------------------------------

Subject: g.region: nsres & ewres are rounded differently

Platform: GNU/Linux/x86
grass obtained from: CVS
grass binary for platform: Compiled from Sources
GRASS Version: 2006-05-18

Hi

nsres & ewres are rounded differently when setting res to something near the decimal places limit.

In [1] both nsres & ewres are rounded-down to 1.12345678 when requested res=1.123456784. That's OK.

But in [2], when requested one decimal point higher res=1.123456785, nsres is rounded-up to 1.12345679 while ewres is rounded-down to 1.12345678.

Moreover, next g.region run [3] with settings identical like in [2] results in ewres=nsres=1.12345678, and, naturaly, different region extent.

Is this all OK? I thought each single, identical g.region run should result in the exactly same region settings.

[1]

$ g.region res=1.123456784 -ap
projection: 1 (UTM)
zone: 33
datum: wgs84
ellipsoid: wgs84
north: 5687680.84554222
south: 5673969.0554935
west: 593389.65108669
east: 603210.91029242
nsres: 1.12345678
ewres: 1.12345678
rows: 12205
cols: 8742

[2]

$ g.region res=1.123456785 -ap
projection: 1 (UTM)
zone: 33
datum: wgs84
ellipsoid: wgs84
north: 5687680.85060488
south: 5673967.93708717
west: 593388.52815808
east: 603210.91082934
nsres: 1.12345678
ewres: 1.12345679
rows: 12206
cols: 8743

[3]

$ g.region res=1.123456785 -ap
projection: 1 (UTM)
zone: 33
datum: wgs84
ellipsoid: wgs84
north: 5687680.85060488
south: 5673966.81363039
west: 593387.4047013
east: 603212.03428612
nsres: 1.12345679
ewres: 1.12345679
rows: 12207
cols: 8745

Maciek

-------------------------------------------- Managed by Request Tracker

Request Tracker wrote:

this bug's URL: http://intevation.de/rt/webrt?serial_num=4469
-------------------------------------------------------------------------

Subject: g.region: nsres & ewres are rounded differently

Platform: GNU/Linux/x86
grass obtained from: CVS
grass binary for platform: Compiled from Sources
GRASS Version: 2006-05-18

Hi

nsres & ewres are rounded differently when setting res to something
near the decimal places limit.

In [1] both nsres & ewres are rounded-down to 1.12345678 when
requested res=1.123456784. That's OK.

But in [2], when requested one decimal point higher res=1.123456785,
nsres is rounded-up to 1.12345679 while ewres is rounded-down to
1.12345678.

Moreover, next g.region run [3] with settings identical like in [2]
results in ewres=nsres=1.12345678, and, naturaly, different region
extent.

Is this all OK? I thought each single, identical g.region run should
result in the exactly same region settings.

If you only specify the res= option, the new bounds will depend upon
the previous bounds.

Ultimately, a region is defined by its bounds and the number of rows
and columns. The resolution is derived from those values, and it may
not be possible to get exactly the value which you requested (as the
result of dividing a floating-point number by an integer may not be
exactly representable as a floating-point number).

The alternative (i.e. to define a region by one corner, the
resolution, and the number of rows and columns, with the other corner
being derived), would be signficantly more awkward to write code for.

--
Glynn Clements <glynn@gclements.plus.com>

I was going to suggest adding a flag to support keeping the resolution
fixed and adjusting the bounds instead, but it appears it is already
there. The -a flag aligns to bounds, so if you type

g.region res=1.23456 -a

the n,s,e, and w bounds will adjust slightly (less than one pixel width)
to keep the resolution fixed at the user specified value.

Though the -a flag works in a strange way in my opinion, it shifts the
boundaries instead of expanding/contracting the boundaries.

Example

g.region rast=test -p
north: 603580
south: 590120
west: 2455900
east: 2465980
nsres: 20
ewres: 20
rows: 673
cols: 504

//nsres gets re-adjusted
g.region rast=test res=40 -p
north: 603580
south: 590120
west: 2455900
east: 2465980
nsres: 39.94065282
ewres: 40
rows: 337
cols: 252

//nsres stays fixed, north and south are shifted
//east and west are also shifted even though they didn't need
//to be adjusted
g.region rast=test res=40 -ap
north: 603600
south: 590120
west: 2455880
east: 2466000
nsres: 40
ewres: 40
rows: 337
cols: 253

I would prefer that either the region boundary be expanded or contracted
by a small amount and not shifted. Let say your original raster is just
the right size and data fills every pixel. If you enlarge the boundary
(rounding up) on the res adjustment, some pixels extend into regions of
possible no data. If you contract the region (round down), you will have
valid data for the entire boundary. If you shift, as is currently the
case, the west/south edges are ok, but east and north may extend into a
no data region.

I think the -a flag is useful for when you want to preserve a particular
res= setting, but the behavior is a little odd.

-Andy

On Thu, 2006-05-18 at 17:54 +0100, Glynn Clements wrote:

Request Tracker wrote:

> this bug's URL: http://intevation.de/rt/webrt?serial_num=4469
> -------------------------------------------------------------------------
>
> Subject: g.region: nsres & ewres are rounded differently
>
> Platform: GNU/Linux/x86
> grass obtained from: CVS
> grass binary for platform: Compiled from Sources
> GRASS Version: 2006-05-18
>
> Hi
>
> nsres & ewres are rounded differently when setting res to something
> near the decimal places limit.
>
> In [1] both nsres & ewres are rounded-down to 1.12345678 when
> requested res=1.123456784. That's OK.
>
> But in [2], when requested one decimal point higher res=1.123456785,
> nsres is rounded-up to 1.12345679 while ewres is rounded-down to
> 1.12345678.
>
> Moreover, next g.region run [3] with settings identical like in [2]
> results in ewres=nsres=1.12345678, and, naturaly, different region
> extent.
>
> Is this all OK? I thought each single, identical g.region run should
> result in the exactly same region settings.

If you only specify the res= option, the new bounds will depend upon
the previous bounds.

Ultimately, a region is defined by its bounds and the number of rows
and columns. The resolution is derived from those values, and it may
not be possible to get exactly the value which you requested (as the
result of dividing a floating-point number by an integer may not be
exactly representable as a floating-point number).

The alternative (i.e. to define a region by one corner, the
resolution, and the number of rows and columns, with the other corner
being derived), would be signficantly more awkward to write code for.

I would prefer that either the region boundary be expanded or
contracted by a small amount and not shifted. Let say your original
raster is just the right size and data fills every pixel. If you
enlarge the boundary (rounding up) on the res adjustment, some pixels
extend into regions of possible no data. If you contract the region
(round down), you will have valid data for the entire boundary. If you
shift, as is currently the case, the west/south edges are ok, but east
and north may extend into a no data region.

I think the -a flag is useful for when you want to preserve a
particular res= setting, but the behavior is a little odd.

It should crop to fit in the x-monitor display?

also watch out for the situation where cells don't align with 10^x,
(grid coords vs cell center conventions)

g.region s=100025 n=101075 res=50

d.zoom will shift to s=100000 n=101050 and data will be shifted in both
x,y by 25m.

Hamish