web-dev-qa-db-fra.com

Conversion des points de latitude et de longitude en UTM

J'ai trouvé un exemple assez simple de la procédure à suivre, mais je ne peux pas le faire fonctionner pour moi. Je suis assez nouveau pour 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

Mais c'est avec des exemples de nombres. J'ai des milliers de coordonnées à transformer et je n'arrive pas à comprendre comment les obtenir de ma table dans ce script

Mon ensemble de données comporte 3 colonnes, ID, X et Y. Comment puis-je les transformer à l'aide de cette équation? Je suis coincé là-dessus depuis des semaines

13
Colin

Pour garantir que les métadonnées de projection appropriées sont associées à chaque étape aux coordonnées, suggérons de convertir les points en un objet SpatialPointsDataFrame dès que possible. 

Voir ?"SpatialPointsDataFrame-class" pour en savoir plus sur la conversion de données simples ou de matrices en SpatialPointsDataFrame objects.

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 
21
Josh O'Brien

Conversion des points de latitude et de longitude en 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)
13
Stanislav

Dans votre question, vous ne savez pas si vous avez déjà lu votre jeu de données dans un data.frame ou une matrice. Donc, je suppose que dans ce qui suit, vous avez vos données dans un fichier texte:

# 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
# ...

Mettre à jour:

Les commentaires suggèrent que le problème vient de l'application de project() à data.frame. project() ne fonctionne pas sur data.frames car il vérifie is.numeric(). Par conséquent, vous devez convertir les données en matrice, comme dans l'exemple ci-dessus. Si vous souhaitez vous en tenir à votre code qui utilise cbind(), vous devez procéder comme suit:

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

La différence entre dd["X"] et dd[,"X"] est que ce dernier ne renvoie pas de nom de données.fr et que, par conséquent, cbind() génère une matrice et non un nom de données.fr.

4
f3lix

Sur la base du code ci-dessus, j'ai également ajouté une version de la détection de zone et d'hémisphère (qui résout les problèmes de conversion, comme décrit dans certains commentaires) + raccourci pour chaîne CRS et conversion en 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") est un raccourci pour CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0").

Recherche de la référence de zone UTM: http://www.igorexchange.com/node/927

0
Teodor Ciuraru