FW: [GRASS-dev] Zooming issue in gis manager

Glynn Clements glynn at gclements.plus.com
Thu Nov 2 19:09:20 EST 2006

Michael Barton wrote:

> The original post here didn't make it past the list file size filter. So
> I've reduced it to one graphic that should make it. I've also done a few
> more tests.
> In addition to what I mention below, g.region run without the -a flag
> creates rounding errors in resolution--minimal but annoying.
> Without the -a flag, the number of cells displayed accurately reflects the
> actual display region setting. So if you save the display region to the WIND
> file, and reset the display to match the new current region (i.e., WIND
> file), it looks the same as before. But, as noted below, it does this by
> shrinking the cells a bit to make them squeeze into the PPM output created
> by the PNG driver (could the X-driver be doing this differently???).

There is no difference between the X and PNG drivers.

However, using direct rendering can potentially produce different
results to using a driver.

Each display frame can have a geographic region associated with it. If
the current frame has a region, this is used in place of the current
region (whether from the WIND file, $WIND_OVERRIDE or $GRASS_REGION).

If you draw something on a monitor, change the current region, then
draw something else without running d.erase, it will use the region
stored on the frame rather than the current region.

This can't happen with direct rendering, as nothing persists between

> With the -a flag, the number of rows or columns displayed is one or two less
> than the number in the display region. This is not noticeable (and maybe
> doesn't even happen) when there are a lot of cells in the display, but can
> be noticeable when there are very few cells in the display. The result is
> that if you copy the display region to the WIND file and display it back
> again, you see more cells than you started with. This is the "correct"
> number of rows and columns, but it not what was displayed. However, there
> are no rounding errors in the resolution as reported by g.region.

"g.region -a" expands the region so that the bounds are aligned to a
grid whose spacing is determine by the existing resolution and whose
alignment is such that the origin of the coordinate system falls on a
grid point (an intersection between four cells).

> Is this all happening in g.region?


> The display driver? Or both? As I say
> below, I can't think of how gis.m could compensate for this. In the region
> computation, it would involve 'rounding' to the nearest resolution value.
> But how can you round to the nearest 0.0001543 degrees? ...or even the
> nearest 25m? There is no 'starting place' to round from, since the region
> boundary can potentially be anywhere theoretically.

First, you have to choose some point which will not change as a result
of the adjustment, e.g. the centre or one of the four corners.

If you pick the south-west corner, then you adjust the north and east
bounds so that the height and width of the region are multiples of the
resolution, i.e.

	width  = east  - west
	height = north - south

	width  = (width  / ewres + 0.5) * ewres	# round to nearest integer multiple of ewres
	height = (height / nsres + 0.5) * nsres	# round to nearest integer multiple of nsres

	east  = west  + width
	north = south + height

The same applies for any other corner, except that either or both of
the last two lines would be replaced by:

	west  = east  - width
	south = north - height

To keep the centre fixed, the last two lines would be replaced by:

	cx = (east  + west ) / 2
	cy = (north + south) / 2
	east  = cx + width  / 2
	west  = cx - width  / 2
	north = cy + height / 2
	south = cy - height / 2

The end result will be similar to using "g.region -a", except that:

1. The grid is anchored at either the centre or a corner of the
region, not the origin of the coordinate system.

2. Each bound is aligned to the nearest grid line, rather than always
rounding outwards.

When panning, you might want to align the region to the previous grid.

If (px, py) is some point which is aligned to the previous grid (e.g.
one corner of a region which was so aligned), then you can align with:

	east  = px + ((east  - px) / ewres) * ewres
	west  = px + ((west  - px) / ewres) * ewres
	north = py + ((north - py) / nsres) * nsres
	south = py + ((south - py) / nsres) * nsres

> I'm going to put the -a flag back into gis.m to keep the resolution rounding
> errors out. If you want to set region with precision, especially in a
> close-up view with few cells showing in a raster, you need to use g.region.
> If you want to display a region in a close-up view of a raster, where the
> cell sizes are large compared with the display and pixel size, you'll need
> to use explore mode for now at least. As documented below and in the
> attached graphic, this does a good job of making a display with accurately
> rendered raster cells. Vectors either don't face these issues or have
> different ones, as they are not behaving parallel to rasters in this.

I think the main point is that you need to keep gis.m's internal
regions valid at all times. Whenever a new region is created due to
zooming or panning, it should be adjusted (so that its size is an
integer multiple of the resolution) as soon as it is created, rather
than storing an invalid region and relying upon it being coerced into
compliance when passed to GRASS (G__read_Cell_head_array() calls
G_adjust_Cell_head(), which affects anything which reads a region).

E.g. if the user marks a rectangle on a map, it should ideally be
adjusted as it is being entered, so that WYSIWYG.

Glynn Clements <glynn at gclements.plus.com>

More information about the grass-dev mailing list