2012-02-08 304 views
15

我正在编写一个程序,它需要一些经纬度点,我将它们内部转换为UTM,以便以米为单位进行一些计算。从经度/纬度确定UTM区域(要转换)

纬度/经度点本身的范围很小 - 约200米x 200米。它们几乎总是可以依赖于单个UTM区域(除非你运气不好并且跨区域边界)。

但是,lat/longs所在的区域是不受限制的。有一天,这个项目可能会在澳大利亚人身上运行(哦,即使是一个国家也会跨越多少个区域,这已经给我带来了多少痛苦......),还有一天是墨西哥人。

我的问题是 - 有没有一种方法来确定哪个区域特定的长/经度,以便它可以被馈送到转换库(我目前使用proj4和R包rgdal)。

我的语言是R,但答案不一定是 - 也许这只是一个简单的计算,或者我可以嵌入系统调用proj exectuable。

欢呼声。

+0

http://stat.ethz.ch/R-manual/R-patched /library/base/html/timezones.html – aatrujillob 2012-02-08 04:47:03

+0

我会建议将此移至gis.stackexchange.com。 – blindjesse 2012-02-08 05:04:08

+0

@AndresT - 这是时区。我想要UTM区域。 – 2012-02-08 05:39:05

回答

33

编辑:对于为所有非极地地区的工作在地球上(非R)代码,请参阅herehere


除非你是在处理数据从几个特殊区域(Svalbard and parts of Norway),这是一个很简单的计算,你可能也只是做自己的R.这里是经度如何与UTM Wikipedia's description区域编号:

UTM系统将80°S和84°N纬度范围内的地球表面划分为60个区域,每个区域宽度为6°经度。 1区覆盖东经180°至174°W;区域编号向东增加至覆盖东经174至180东区的区域60。

因此,假设您的数据经度为Prime Meridian以西编码为-180至0度运行,这里是上述的R-代码版本:

long2UTM <- function(long) { 
    (floor((long + 180)/6) %% 60) + 1 
} 

# Trying it out for San Francisco, clearly in UTM Zone 10 
# in the figure in the Wikipedia article linked above 
SFlong <- -122.4192 
long2UTM(SFlong) 
# [1] 10 

那表情显然可以简化一下,但我认为在这种形式下,其构建的逻辑是最清楚的。 %% 60位在那里,以防万一你的经度大于180或小于-180。

+0

啊哈,这是我之后的计算 - 我花了几年谷歌搜索“如何从经度/纬度计算UTM区域”,甚至没有考虑检查维基。干杯! – 2012-02-08 07:04:56

+0

是的,我不久前经历了同样的过程。很高兴能帮上忙。顺便说一下,如果您将空间数据用得很多,那么[R-sig-geo](https://stat.ethz.ch/mailman/listinfo/r-sig-geo)列表服务是非常宝贵的。我最近在那里问了一个问题,接近Roger Bivand本人的帮助,他给了我一个答案,除了他和几个R-核心成员本可以提供的人之外,没有人能够提供。干杯! – 2012-02-08 07:09:54

+0

@ToolmakerSteve - 感谢您提供的更正(5位SO编辑者中的3位错误地拒绝了他们的评论)。 – 2013-01-28 06:21:05

2

我不知道R-代码,但我想这PL/SQL代码可以帮助你的例外:

UTMZone := Trunc((lon - Zone0WestMeridian)/d); 
    --Special Cases for Norway & Svalbard 
    CASE 
    WHEN (lat > 55) AND (UTMZone = 31) AND (lat < 64) AND (lon > 2) THEN UTMZone := 32; 
    WHEN (lat > 71) AND (UTMZone = 32) AND (lon < 9) THEN UTMZone := 31; 
    WHEN (lat > 71) AND (UTMZone = 32) AND (lon > 8) THEN UTMZone := 33; 
    WHEN (lat > 71) AND (UTMZone = 34) AND (lon < 21) THEN UTMZone := 33; 
    WHEN (lat > 71) AND (UTMZone = 34) AND (lon > 20) THEN UTMZone := 35; 
    WHEN (lat > 71) AND (UTMZone = 36) AND (lon < 33) THEN UTMZone := 35; 
    WHEN (lat > 71) AND (UTMZone = 36) AND (lon > 32) THEN UTMZone := 37; 
    ELSE UTMZone := UTMZone; 
    END CASE;