Skip to content

Again, coordinate interpolation with NAs

4 messages · Mario A. Pardo, Karl Ove Hufthammer, Edzer Pebesma +1 more

#
Hi all,

I'm changing the way of my question, since it was missunderstood before.

Given:

lon <- c(-115.86, -115.83, NA, -115.78, -115.78, -115.75, NA, -115.68, 
-115.66)
lat <- c(  29.76,   29.61, NA,   29.55,   29.53,   29.41, NA, 29.13,   
29.09)

I need a new set of coordinates interpolated at a given resolution, 
let's say one data point each xx kilometers or degrees, or at a given 
proportion of the total length, etc.

BUT,

Think of this coordinates as transect points, and I need to keep the 
NAs, since they mark cut offs in my transect. The only think that I need 
is to increase the number of data points in each transect. That means 
that the new.lon would be constitued by values interpolated between the 
first two points (-115.86 and -115.83); after them, a NA should be 
placed, marking a cut off in the transect, then the interpolated data of 
the next three points (-115.78, -115.78 and -115.75), then a NA... and 
so forth. Off course, the new.lat should be the same length as new.lon 
with NAs placed at the same places. As far as I have tried, neither the 
function "approx" or "expand.grid" can do that. I know this is not a 
Matllab list, but since I recently moved from Matlab to R, I just want 
to point out that the function "interpm" does exactly that, just in case 
somebody here knows it.

Thanks! and sorry for the insistence.
#
Mario A. Pardo skreiv:
I would recommend using SpatialLines objects instead, which can 
easily hold polylines and multiple lines. Example:

library(sp)
library(geosphere)

lon=c(-115.86, -115.83, NA, -115.78, -115.78, -115.75, NA, -115.68, -115.66)
lat=c(  29.76,   29.61, NA,   29.55,   29.53,   29.41, NA, 29.13, 29.09)
d=data.frame(lon,lat)        # Convert to data frame
d$group=cumsum(is.na(d$lon)) # Add line ID
d=d[!is.na(d$lon),]          # Remove NA rows

d.lines=split(d,d$group)    # Split by line ID

# Convert into SpatialLines object
d.sp=SpatialLines(lapply(d.lines, function(df) Lines(Line(df[c("lon","lat")]), ID=df$group[1])),
                  proj4string=CRS("+proj=longlat"))

# Add intermediate points
d.sp.int=makeLine(d.sp, interval=1000)


# The actual coordinates are available in this list
# (though I don?t know why there are duplicates ?
# a small bug in makeLine, perhaps?):
lapply(d.sp.int at lines, function(x) x at Lines[[1]]@coords)
#
On 08/29/2012 07:04 PM, Karl Ove Hufthammer wrote:
I was thinking along the same line. I'm curious, btw, whether matlab's
interpm also interpolates along great circle lines, as makeLine does.

An alternative that interpolates along straight lines, building on your
script, is:

x = spsample(d.sp, type = "regular", n = 100)
plot(x, cex=.2, axes=TRUE)

but I'm not sure whether the first and last points are always included.
#
On Wed, 29 Aug 2012, Mario A. Pardo wrote:

            
In addition to the other comments, using NA coordinates is a legacy 
representation to split line objects, and may be converted to a 
SpatialLines object:

library(maptools)
x <- c(-115.86, -115.83, NA, -115.78, -115.78, -115.75, NA, -115.68,
  -115.66)
y <- c(29.76, 29.61, NA, 29.55, 29.53, 29.41, NA, 29.13, 29.09)
map <- list(x=x, y=y)
sp_map <- map2SpatialLines(map)
length(slot(sp_map, "lines"))
plot(sp_map, col=1:length(slot(sp_map, "lines")), axes=TRUE)
library(rgeos)
gLength(sp_map, byid=TRUE)

gives the lengths (assuming planar geometry). How you handle getting 
additional points will depend on whether the coordinates are projected or 
not. If not, you need to use Great Circle distances, and introduce points 
on the azimuth. trackAzimuth() in maptools goes the other way, from a 
matrix of coordinates to a vector of azimuths.

trackAzimuth(cbind(x=x, y=y))

It may be easier for the small distances involved here (km):

sapply(slot(sp_map, "lines"), LinesLength, longlat=TRUE)

to project and create the new points planar, then go back to longlat if 
you need GPS - for this see also export of GPX files in writeOGR() in 
rgdal.

Hope this clarifies,

Roger