【问题标题】:Converting latitude and longitude points to UTM将纬度和经度点转换为 UTM
【发布时间】:2013-09-09 12:04:00
【问题描述】:

我找到了一个相当简单的示例来说明如何执行此操作,但我无法让它为我工作。我对 R 很陌生

library(rgdal) 
xy <- cbind(c(118, 119), c(10, 50)) 
project(xy, "+proj=utm +zone=51 ellps=WGS84") 
          [,1]    [,2] 
[1,] -48636.65 1109577 
[2,] 213372.05 5546301

但这是示例数字。我有数千个坐标需要转换,但我不知道如何将它们从我的表中获取到这个脚本中

我的数据集有 3 列,ID、X 和 Y。如何使用这个等式转换它们?我已经坚持了好几个星期了

【问题讨论】:

  • 如果您不向我们提供一些不起作用的数字(可能还包括对它们使用的格式的一些描述),我们将很难为您提供帮助'被存储)。另外,您知道您所有的经纬坐标都属于一个 UTM 区域吗?
  • 好吧,数字不起作用并不是因为我没有输入数字。我需要脚本从包含数千个坐标的表中读取它。我只是不知道该怎么做。 dd
  • 什么样的桌子? (它是否存储在文本文件中?一个 csv?一个关系数据库?一个 Excel 文件?等等等等。)听起来你真的在问如何将数据读入 R。在这种情况下,试试使用 Google 或在右上角的 SO 搜索栏中搜索,然后再询问您是否无法弄清楚。
  • 我不知道如何读入数据。它是一个csv文件。上面的示例是示例编号。我的问题是在我从表中读取 X(经度)和 Y(纬度)之后。该数据如何适合示例脚本

标签: r coordinates rgdal


【解决方案1】:

在您的问题中,您不清楚您是否已经将数据集读入 data.frame 或矩阵。所以我假设在下面你有你的数据集在一个文本文件中:

# read in data
dataset = read.table("dataset.txt", header=T)

# ... or use example data
dataset = read.table(text="ID X Y
1 118 10
2 119 50
3 100 12
4 101 12", header=T, sep=" ")

# create a matrix from columns X & Y and use project as in the question
project(as.matrix(dataset[,c("X","Y")]), "+proj=utm +zone=51 ellps=WGS84")
#             [,1]    [,2]
# [1,]   -48636.65 1109577
# [2,]   213372.05 5546301
# ...

更新:

cmets 表明问题来自于将project() 应用于data.frame。 project() 不适用于 data.frames,因为它会检查 is.numeric()。因此,您需要将数据转换为矩阵,如我上面的示例所示。如果您想坚持使用 cbind() 的代码,您必须执行以下操作:

 X <- dd[,"X"]
 Y <- dd[,"Y"]
 xy <- cbind(X,Y) 

dd["X"]dd[,"X"] 之间的区别在于后者不会返回 data.frame,因此cbind() 将产生一个矩阵而不是一个 data.frame。

【讨论】:

  • 谢谢。这似乎确实产生了一些令人宽慰的东西!输出是米吗?我的大部分坐标现在看起来像 -9596387 -5670257、-9597204 -5666367 等。这看起来对吗?有些人提到了 UTM 区域。如果有意义的话,我从谷歌建议似乎分布在 39 l、39 K 和 38 k 上。是否必须在脚本中考虑到这一点。正如我所说,我只是复制了一个我在网上找到的例子。对不起,如果我听起来像个白痴,我只是想了解一下。再次感谢
【解决方案2】:

为确保在与坐标相关的每个步骤中都有适当的投影元数据,我建议尽快将这些点转换为 SpatialPointsDataFrame 对象。

有关如何将简单的 data.frames 或矩阵转换为 SpatialPointsDataFrame 对象的更多信息,请参阅 ?"SpatialPointsDataFrame-class"

library(sp)
library(rgdal)

xy <- data.frame(ID = 1:2, X = c(118, 119), Y = c(10, 50))
coordinates(xy) <- c("X", "Y")
proj4string(xy) <- CRS("+proj=longlat +datum=WGS84")  ## for example

res <- spTransform(xy, CRS("+proj=utm +zone=51 ellps=WGS84"))
res
#            coordinates ID
# 1 (-48636.65, 1109577)  1
# 2    (213372, 5546301)  2

## For a SpatialPoints object rather than a SpatialPointsDataFrame, just do: 
as(res, "SpatialPoints")
# SpatialPoints:
#              x       y
# [1,] -48636.65 1109577
# [2,] 213372.05 5546301
# Coordinate Reference System (CRS) arguments: +proj=utm +zone=51
# +ellps=WGS84 

【讨论】:

  • spTransform() 调用中的变量“SP”是什么?如果我将其更改为“xy”,则不会得到与该调用下方所示相同的输出。
  • @stackoverflowuser2010 -- 糟糕,我的错。 SP 是我最初的回答留下的,因为经过编辑,它涉及 SpatialPoints 对象而不是 SpatialPointsDataFrame。为了您将来的参考,您可以通过单击已编辑答案正下方的“已编辑...以前”链接来查看早期版本的 SO 答案。感谢您了解这一点。
【解决方案3】:

将经纬度点转换为 UTM

library(sp)
library(rgdal)

#Function
LongLatToUTM<-function(x,y,zone){
 xy <- data.frame(ID = 1:length(x), X = x, Y = y)
 coordinates(xy) <- c("X", "Y")
 proj4string(xy) <- CRS("+proj=longlat +datum=WGS84")  ## for example
 res <- spTransform(xy, CRS(paste("+proj=utm +zone=",zone," ellps=WGS84",sep='')))
 return(as.data.frame(res))
}

# Example
x<-c( -94.99729,-94.99726,-94.99457,-94.99458,-94.99729)
y<-c( 29.17112, 29.17107, 29.17273, 29.17278, 29.17112)
LongLatToUTM(x,y,15)

【讨论】:

    【解决方案4】:

    基于上面的代码,我还添加了一个版本的区域和半球检测(解决转换问题,如某些 cmets 中所述)+ CRS 字符串的简写并转换回 WSG86:

    library(dplyr)
    library(sp)
    library(rgdal)
    library(tibble)
    
    find_UTM_zone <- function(longitude, latitude) {
    
     # Special zones for Svalbard and Norway
        if (latitude >= 72.0 && latitude < 84.0 ) 
            if (longitude >= 0.0  && longitude <  9.0) 
                  return(31);
        if (longitude >= 9.0  && longitude < 21.0)
              return(33)
        if (longitude >= 21.0 && longitude < 33.0)
              return(35)
        if (longitude >= 33.0 && longitude < 42.0) 
              return(37)
    
        (floor((longitude + 180) / 6) %% 60) + 1
    }
    
    
    find_UTM_hemisphere <- function(latitude) {
    
        ifelse(latitude > 0, "north", "south")
    }
    
    # returns a DF containing the UTM values, the zone and the hemisphere
    longlat_to_UTM <- function(long, lat, units = 'm') {
    
        df <- data.frame(
            id = seq_along(long), 
            x = long, 
            y = lat
        )
        sp::coordinates(df) <- c("x", "y")
    
        hemisphere <- find_UTM_hemisphere(lat)
        zone <- find_UTM_zone(long, lat)
    
        sp::proj4string(df) <- sp::CRS("+init=epsg:4326") 
        CRSstring <- paste0(
            "+proj=utm +zone=", zone,
            " +ellps=WGS84",
            " +", hemisphere,
            " +units=", units)
        if (dplyr::n_distinct(CRSstring) > 1L) 
            stop("multiple zone/hemisphere detected")
    
        res <- sp::spTransform(df, sp::CRS(CRSstring[1L])) %>%
            tibble::as_data_frame() %>%
            dplyr::mutate(
                zone = zone,
                hemisphere = hemisphere
            )
    
        res
    }
    
    UTM_to_longlat <- function(utm_df, zone, hemisphere) {
    
        CRSstring <- paste0("+proj=utm +zone=", zone, " +", hemisphere)
        utmcoor <- sp::SpatialPoints(utm_df, proj4string = sp::CRS(CRSstring))
        longlatcoor <- sp::spTransform(utmcoor, sp::CRS("+init=epsg:4326"))
        tibble::as_data_frame(longlatcoor)
    }
    

    其中CRS("+init=epsg:4326")CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0") 的简写。

    查找 UTM 区域引用:http://www.igorexchange.com/node/927

    【讨论】:

      【解决方案5】:

      关于示例,给定坐标的默认 UTM 区域为 50。不建议将坐标投影到较远的区域。您可以使用来自 NOAA 的 NCAT tool 检查转换。

      下面的代码使用sf 包进行转换。

      library(sf)
      library(tidyverse)
      
      # Coordinate examples with expected UTM values
      coord_sample <- data.frame(
        "Northing" = c(1105578.589, 5540547.370),
        "Easting" = c(609600.773, 643329.124),
        "Latitude" = c(10, 50),
        "Longitude" = c(118, 119))
      
      #' Find UTM EPSG code from Latitude and Longitude coordinates (EPSG 4326 WGS84)
      #' (vectorised)
      #' Source: https://geocompr.robinlovelace.net/reproj-geo-data.html
      #' Source: https://gis.stackexchange.com/questions/13291/computing-utm-zone-from-lat-long-point
      LatLonToUTMEPSGCode <- function(lat, lon) {
      
        zone_number <- (floor((lon + 180) / 6) %% 60) + 1
      
        # Special zones for Norway
        cond_32 <- lat >= 56.0 & lat < 64.0 & lon >= 3.0 & lon < 12.0
        zone_number[cond_32] <- 32
      
        # Special zones for Svalbard
        cond_lat <- lat >= 72.0 & lat < 84.0
      
        cond_31 <- cond_lat & lon >= 0.0 & lon <  9.0
        zone_number[cond_31] <- 31
      
        cond_33 <- cond_lat & lon >= 9.0 & lon < 21.0
        zone_number[cond_33] <- 33
      
        cond_35 <- cond_lat & lon >= 21.0 & lon < 33.0
        zone_number[cond_35] <- 35
      
        cond_37 <- cond_lat & lon >= 33.0 & lon < 42.0
        zone_number[cond_37] <- 37
      
        # EPSG code
        utm <- zone_number
        utm[lat > 0] <- utm[lat > 0] + 32600
        utm[lat <= 0] <- utm[lat <= 0] + 32700
      
        return(utm)
      }
      
      sf_sample <- sf::st_as_sf(coord_sample, coords = c("Longitude", "Latitude"),
                                crs = 4326)
      
      sf_sample %>%
        do(cbind(., st_coordinates(.))) %>%
        mutate(EPSG = LatLonToUTMEPSGCode(lat = Y, lon = X)) %>%
        group_by(EPSG) %>%
        do(cbind(as.data.frame(.) %>% select(Northing, Easting),
                 st_coordinates(st_transform(., crs = head(.$EPSG, 1))))) %>%
        ungroup()
      
      
      

      您可以通过与预期值比较来检查转换:

      # A tibble: 2 x 5
         EPSG Northing Easting      X       Y
        <dbl>    <dbl>   <dbl>  <dbl>   <dbl>
      1 32650  1105579  609601 609601 1105579
      2 32650  5540547  643329 643329 5540547
      

      【讨论】:

        猜你喜欢
        • 2011-02-11
        • 2010-09-15
        • 2016-07-30
        • 2021-05-21
        • 2019-03-01
        • 2018-02-03
        • 2011-02-10
        • 1970-01-01
        • 2021-07-18
        相关资源
        最近更新 更多