Skip to content

flip SpatialGridDataFrame across axis

7 messages · Sébastien Bihorel, Edzer Pebesma, Michael Sumner

#
Hi,

After importing a grid with readGDAL(), a `SpatialGridDataFrame' object
is produced that looks correct, except the y-axis is flipped upside
down, despite the note in the "Value" section in ?readGDAL.  So I need
to flip the grid across the horizontal axis, and searching the archives
points to an old reference to elide() in maptools.  However, this
doesn't take a `SpatialGridDataFrame', so I'd appreciate any suggestions
for better alternatives.  Thanks.

Cheers,
#
Hi Sebastian, I think the "north-south" note is referring to
possibly-rotated grids (using the transform values supported by many
formats) - not to "north vs. south" in orientation.

You can easily flip a grid by reverting it (one band at a time) to an
xyz image and using indexing. I find this approach the least confusing
and easily repeatable.

library(rgdal)
data(meuse.grid)
coordinates(meuse.grid) <- ~x+y
gridded(meuse.grid) <- TRUE
fullgrid(meuse.grid) <- TRUE
image(meuse.grid[3])

## note this method only works on single bands at once
x1 <- as.image.SpatialGridDataFrame(meuse.grid[3])

## reverse the Y by indexing in to the (image) xyz list
x1$z <- x1$z[,ncol(x1$z):1]

## convert to SGDF
flipY <- image2Grid(x1, p4 = as.character(proj4string(meuse.grid)))
contour(flipY, add = TRUE)

It would not be difficult to adapt this to flip each band
sequentially, and use the internal arrangement of the
SpatialGrid/Pixels classes directly - but this is enough for me.

Regards, Mike.
On Tue, Nov 3, 2009 at 7:05 AM, Sebastian P. Luque <spluque at gmail.com> wrote:
#
On Tue, 3 Nov 2009 07:40:59 +1100,
Michael Sumner <mdsumner at gmail.com> wrote:

            
[...]

Thanks for the quick reply Mike!!


Cheers,
#
It would be nice if the "[" methods on ?'SpatialGridDataFrame-class'
could perform the same indexing orientation, but that uses the
row/column values for [i,j,...]  to obtain the subsetted cells which
are regridded via SpatialPixels - so the direction is lost. I'm not
sure it's a good idea to modify that - given that the indexing could
be used to subset at the same time - which is probably why the authors
have written it that way.  ;)

But, I've been meaning to try something like this for ages, and this
seems to work:

flipHorizontal <- function(x) {
	if (!inherits(x, "SpatialGridDataFrame")) stop("x must be a
SpatialGridDataFrame")
	grd <- getGridTopology(x)
	idx = 1:prod(grd at cells.dim[1:2])
	m = matrix(idx, grd at cells.dim[2], grd at cells.dim[1], byrow =
TRUE)[,grd at cells.dim[1]:1]
	idx = as.vector(t(m))
	x at data <- x at data[idx, TRUE, drop = FALSE]
	x
}

flipVertical <- function(x) {
	if (!inherits(x, "SpatialGridDataFrame")) stop("x must be a
SpatialGridDataFrame")
	grd <- getGridTopology(x)
	idx = 1:prod(grd at cells.dim[1:2])
	m = matrix(idx, grd at cells.dim[2], grd at cells.dim[1], byrow =
TRUE)[grd at cells.dim[2]:1, ]
	idx = as.vector(t(m))
	x at data <- x at data[idx, TRUE, drop = FALSE]
	x
}

The approach there is stolen from 'subs.SpatialGridDataFrame' in
sp/R/SpatialGridDataFrame-methods.R - so thanks as ever to the
authors!

Cheers, Mike.
On Tue, Nov 3, 2009 at 7:49 AM, Sebastian P. Luque <spluque at gmail.com> wrote:
#
Ergh, sorry for the update -  a pox on Gmail for sabotaging my
attempts at plain text!  I've attached the functions in a text file to
avoid [ampersand] to " at " conversion ...




---------- Forwarded message ----------
From: Michael Sumner <mdsumner at gmail.com>
Date: Tue, Nov 3, 2009 at 8:45 AM
Subject: Re: [R-sig-Geo] flip SpatialGridDataFrame across axis
To: r-sig-geo at stat.math.ethz.ch


It would be nice if the "[" methods on ?'SpatialGridDataFrame-class'
could perform the same indexing orientation, but that uses the
row/column values for [i,j,...] ?to obtain the subsetted cells which
are regridded via SpatialPixels - so the direction is lost. I'm not
sure it's a good idea to modify that - given that the indexing could
be used to subset at the same time - which is probably why the authors
have written it that way. ?;)

But, I've been meaning to try something like this for ages, and this
seems to work:

flipHorizontal <- function(x) {
? ? ? ?if (!inherits(x, "SpatialGridDataFrame")) stop("x must be a
SpatialGridDataFrame")
? ? ? ?grd <- getGridTopology(x)
? ? ? ?idx = 1:prod(grd at cells.dim[1:2])
? ? ? ?m = matrix(idx, grd at cells.dim[2], grd at cells.dim[1], byrow =
TRUE)[,grd at cells.dim[1]:1]
? ? ? ?idx = as.vector(t(m))
? ? ? ?x at data <- x at data[idx, TRUE, drop = FALSE]
? ? ? ?x
}

flipVertical <- function(x) {
? ? ? ?if (!inherits(x, "SpatialGridDataFrame")) stop("x must be a
SpatialGridDataFrame")
? ? ? ?grd <- getGridTopology(x)
? ? ? ?idx = 1:prod(grd at cells.dim[1:2])
? ? ? ?m = matrix(idx, grd at cells.dim[2], grd at cells.dim[1], byrow =
TRUE)[grd at cells.dim[2]:1, ]
? ? ? ?idx = as.vector(t(m))
? ? ? ?x at data <- x at data[idx, TRUE, drop = FALSE]
? ? ? ?x
}

The approach there is stolen from 'subs.SpatialGridDataFrame' in
sp/R/SpatialGridDataFrame-methods.R - so thanks as ever to the
authors!

Cheers, Mike.
On Tue, Nov 3, 2009 at 7:49 AM, Sebastian P. Luque <spluque at gmail.com> wrote:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: flipSGDF.R
Type: application/octet-stream
Size: 694 bytes
Desc: not available
URL: <https://stat.ethz.ch/pipermail/r-sig-geo/attachments/20091103/04a86c36/attachment.obj>
#
Michael, to be hounest, it even surprised me, being the author, that

data(meuse.grid)
gridded(meuse.grid) = ~x+y
fullgrid(meuse.grid) = TRUE
image(meuse.grid[104:1,])

would not flip the image. It just works hard to not destroy the spatial
location of all individual pixels -- it will select all rows in reverse
order, but in the end put everything back in place. What you do is kind
of more like image analysis, as it  moves the location of pixels, right?

Do you mind if we add your flipXxx functions to sp?
--
Edzer
Michael Sumner wrote:

  
    
#
Hi Edzer, no problem at all - Robert's approach is much less verbose,
but I think this explicit method is easier to understand and share as
it exposes the underlying indexing.

I agree there's a sense that it is image processing, but in the "GIS
raster" sense (image, DEM, data, etc.)  it's a useful way of
correcting broken or incomplete metadata - and with the range of
orientation conventions and ways of storing those it's handy to have.

Do you think it belongs as a method in the maptools elide family - at
least eventually?  I guess that depends on future support for rasters
there.  Given the terminology used there it's probably better to call
the functions "reflectHorizontal/Vertical" rather than flip, even if
they exist as standalones for now?

Regards, Mike.

On Tue, Nov 3, 2009 at 7:13 PM, Edzer Pebesma
<edzer.pebesma at uni-muenster.de> wrote: