[英]reverse map-projection: how to get lat/lon coordinates from projected coordinates
I have a set of lat/lon coords which I can project using, for example, Mollweide projection.我有一组经纬度坐标,我可以使用例如 Mollweide 投影进行投影。
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]
?例如,如何反向投影红点
[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.我不知道您是否有理由需要首先使用
mapproject
进行投影。 If you can use spTransform
instead, then this becomes easier because you can also use spTransform
to reverse the same process.如果您可以改用
spTransform
,那么这会变得更容易,因为您还可以使用spTransform
来反转相同的过程。
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 Ie the points are normalised to lie between -1 to 1 latitude and -2 to 2 longitude.假设您确实需要使用
mapproject
,我们仍然可以使用spTransform
将点从您的投影坐标系转换为经纬度坐标,但需要更多的摆弄来处理mapproject
投影的非标准格式,即点被标准化为位于 -1 到 1 纬度和 -2 到 2 经度之间。 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:所以,首先我们可以使用 spTransform 找出我们需要将归一化的 mapproject 坐标转换为实际距离所需的转换因子:
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
.最后,我们需要按经度旋转这些点,以撤消在
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
If nothing out of the box is available, you could write a function of your own, along the lines of:如果没有开箱即用的功能,您可以编写自己的函数,如下所示:
ref_project <- function(x, y) {
long <- tibble(
long = seq(-180, 180, 1),
x = mapproject(long, rep(0, length(long)), projection = 'mollweide', orientation = c(90, 200, 0))$x
)
lat <- tibble(
lat = seq(-90, 90, 1),
x = mapproject(rep(0, length(lat)), lat, projection = 'mollweide', orientation = c(90, 200, 0))$y
)
return(c(long[which(abs(long$x - x) == min(abs(long$x - x))), 'long'],
lat[which(abs(lat$x - y) == min(abs(lat$x - y))), 'lat']))
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.