今天我遇到了一个问题,需要找到全球各地点的经纬度对应的UTM带。问题在于存在许多特殊情况,例如挪威斯瓦尔巴群岛和两极地区
(在这张地图上以红色标出),如果你认为它是规则的,那么你会被这些特殊情况搞糊涂!
下面是我的R函数,用于查找经纬度对应的UTM带,并在最后进行所有特殊情况的测试。
require(tidyverse)
require(purrr)
require(testthat)
find_one_utm_zone <- function(longitude, latitude) {
if (latitude >= 72.0 && latitude <= 84.0 ) {
if (longitude >= 0.0 && longitude < 9.0)
return("31X");
if (longitude >= 9.0 && longitude < 21.0)
return("33X")
if (longitude >= 21.0 && longitude < 33.0)
return("35X")
if (longitude >= 33.0 && longitude < 42.0)
return("37X")
}
if (latitude >= 56.0 && latitude < 64.0 ) {
if (longitude >= 0.0 && longitude < 3.0)
return("31V");
if (longitude >= 3.0 && longitude < 12.0)
return("32V")
}
if (latitude > 84.0){
if ((longitude+180)%%360-180 < 0) {return("Y")}
if ((longitude+180)%%360-180 > 0) {return("Z")}
} else if (latitude < -80.0){
if ((longitude+180)%%360-180 < 0) {return("A")}
if ((longitude+180)%%360-180 > 0) {return("B")}
}
if ( (latitude>-80.0) && (latitude<=84.0) ){
mid_zones <- LETTERS[c(3:8,10:14,16:24)]
utm_letter <- mid_zones[ min(floor( (latitude + 80) / 8 )+1 , 20) ]
utm_number <- (floor( (longitude + 180) / 6 ) %% 60) + 1
utm_zone <- paste0(utm_number, utm_letter)
return(utm_zone)
} else {
stop("lat long not valid (or something else broke)")
}
}
find_utm_zone <- function(lon, lat){
purrr::map2_chr(.x = lon, .y = lat, .f = find_one_utm_zone)
}
使用示例
locs <-
tibble(lon = c(-100,30,150, 4, 7, 22, 0, 12, -34, -20),
lat = c(-45, 85, 12, 57, 81, 83, 5, -81, 85, 83),
desired_utm_zone = c("14G","Z","56P", "32V" ,"31X","35X","31N", "B","Y","27X"))
locs2 <-
locs %>%
mutate(utm_zone = find_utm_zone(lon = lon,lat = lat))
测试它是否有效:
测试一下:
testthat::expect_equal(locs2$utm_zone, locs2$desired_utm_zone)