I have a set of lat/lon coords which I can project using, for example, Mollweide projection.
library(mapproj)
set.seed(0)
n <- 100
s <- data.frame(lon = rnorm(n, 0, 60),
lat = rnorm(n, 0, 40))
p <- mapproject(s$lon, s$lat, proj="mollweide", par=NULL,
orientation=c(90,200,0))
# plot projected coors
plot(p$x, p$y, type="n", asp=1/1, bty="n")
map.grid(c(-180, 180, -90, 90), nx=20, ny=20,
font=1, col=grey(.6), labels=F)
points(p$x, p$y, pch="x", cex = .8)
# a point to reverse project
points(1,0, pch=16, col="red", cex=2)
Now, I have a scenario where I need to do some calculations on the projected coordinates and reverse project the results back to lat/lon coords. For example, how can I reverse project the red point [1,0]
?
Any ideas how that can be done?
I don't know if there's a reason you need to use mapproject
to project in the fist place. If you can use spTransform
instead, then this becomes easier because you can also use spTransform
to reverse the same process.
Assuming that you do need to use mapproject
, we can still use spTransform
to convert points from your projected coordinate system into lat-long coordinates, but a little more fiddling is required to deal with the non-standard format of the mapproject
projections I.e. the points are normalised to lie between -1 to 1 latitude and -2 to 2 longitude. In more standard map projections the lat/long are expressed in distances (usually meters).
So, first we can use spTransform to find out the conversion factors we need to convert the normalised mapproject coordinates into actual distances:
library(rgdal)
my.points = data.frame(x=c(0,180),y=c(90,0))
my.points = SpatialPoints(my.points, CRS('+proj=longlat'))
my.points = spTransform(my.points, CRS('+proj=moll'))
# SpatialPoints:
# x y
# [1,] 0 9020048
# [2,] 18040096 0
# Coordinate Reference System (CRS) arguments: +proj=moll +ellps=WGS84
Now we can use these references to convert from normalised mapproject coordinates into distances in meters:
my.points = data.frame(x=p$x * 18040096/2 , y=p$y * 9020048)
my.points = SpatialPoints(my.points, CRS('+proj=moll'))
And reproject these into lat/long geographic coordinates:
my.points = as.data.frame(spTransform(my.points, CRS('+proj=longlat')))
Finally we need to rotate these points by longitude, to undo the rotation that was performed in mapproject
.
my.points$x = my.points$x + 200
my.points$x[my.points$x > 180] = my.points$x[my.points$x > 180] - 360
And lets check that it worked:
head(my.points)
# x y
# 1 75.77725 31.274368
# 2 -19.57400 -31.071065
# 3 79.78795 -24.639597
# 4 76.34576 1.863212
# 5 24.87848 -45.215432
# 6 -92.39700 23.068752
head(s)
# lon lat
# 1 75.77726 31.274367
# 2 -19.57400 -31.071065
# 3 79.78796 -24.639596
# 4 76.34576 1.863212
# 5 24.87849 -45.215431
# 6 -92.39700 23.068751