简体   繁体   English

反向地图投影:如何从投影坐标中获取纬度/经度坐标

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM