online - convertir coordenadas utm a geograficas
Convertir coordenadas geográficas de grado a decimal (7)
Quiero convertir mis coordenadas geográficas de grados a decimales, mis datos son los siguientes:
lat long
105252 30°25.264 9°01.331
105253 30°39.237 8°10.811
105255 31°37.760 8°06.040
105258 31°41.190 8°06.557
105259 31°41.229 8°06.622
105260 31°38.891 8°06.281
Tengo este código pero no puedo ver por qué no funciona:
convert<-function(coord){
tmp1=strsplit(coord,"°")
tmp2=strsplit(tmp1[[1]][2],"//.")
dec=c(as.numeric(tmp1[[1]][1]),as.numeric(tmp2[[1]]))
return(dec[1]+dec[2]/60+dec[3]/3600)
}
don_convert=don1
for(i in 1:nrow(don1)){don_convert[i,2]=convert(as.character(don1[i,2])); don_convert[i,3]=convert(as.character(don1[i,3]))}
La función de conversión funciona, pero el código en el que le pido al bucle que haga el trabajo por mí no funciona.
Cualquier sugerencia es mencionada.
Como Jim Lewis comentó antes, parece que estás usando minutos de punto flotante. Entonces solo concatena dos elementos en
dec = c (como.numérico (tmp1 [[1]] [1]), como.numérico (tmp2 [[1]]))
Teniendo grados, minutos y segundos en la forma 43 ° 21''8.02 que as.character()
devuelve "43 ° 21''8.02 /" ", actualicé su función a
convert<-function(coord){
tmp1=strsplit(coord,"°")
tmp2=strsplit(tmp1[[1]][2],"''")
tmp3=strsplit(tmp2[[1]][2],"/"")
dec=c(as.numeric(tmp1[[1]][1]),as.numeric(tmp2[[1]][1]),as.numeric(tmp3[[1]]))
c<-abs(dec[1])+dec[2]/60+dec[3]/3600
c<-ifelse(dec[1]<0,-c,c)
return(c)
}
Agregando la alternativa para las coordenadas negativas, y funciona muy bien para mí. Todavía no entiendo por char2dms
función char2dms
en la biblioteca sp
no me funcionó.
Gracias
Echa un vistazo al degree
comando en el paquete OSMscale
.
Gracias por las respuestas de @Gord Stephen y @CephBirk. Claro que me ayudó. Pensé que solo mencionaría que también encontré que las measurements::conv_unit
no se ocupa de las entradas "E / W" "N / S", requiere grados positivos / negativos. Mis coordenadas vienen como cadenas de caracteres "1 1 1W"
y primero deben convertirse a "-1 1 1"
.
Pensé que iba a compartir mi solución para eso.
df <- c("1 1 1E", "1 1 1W", "2 2 2N","2 2 2S")
measurements::conv_unit(df, from = ''deg_min_sec'', to = ''dec_deg'')
[1] "1.01694444444444" NA NA NA
Warning message:
In split(as.numeric(unlist(strsplit(x, " "))) * c(3600, 60, 1), :
NAs introduced by coercion
ewns <- ifelse( str_extract(df,"//(?[EWNS,.]+//)?") %in% c("E","N"),"+","-")
dms <- str_sub(df,1,str_length(df)-1)
df2 <- paste0(ewns,dms)
df_dec <- measurements::conv_unit(df2,
from = ''deg_min_sec'',
to = ''dec_deg''))
df_dec
[1] "1.01694444444444" "-1.01694444444444" "2.03388888888889" "-2.03388888888889"
as.numeric(df_dec)
[1] 1.016944 -1.016944 2.033889 -2.033889
Intente usar la función char2dms
en la biblioteca sp
. Tiene otras funciones que además harán conversión decimal.
library("sp")
?char2dms
Otra opción menos elegante usando subcadenas en lugar de strsplit. Esto solo funcionará si todas sus posiciones tienen el mismo número de dígitos. Para las coordenadas negativas, simplemente multiplique por -1 para obtener el grado decimal correcto.
x$LatDD<-(as.numeric(substring(x$lat, 1,2))
+ (as.numeric(substring(x$lat, 4,9))/60))
x$LongDD<-(as.numeric(substring(x$long, 1,1))
+ (as.numeric(substring(x$long, 3,8))/60))
Un poco de vectorización y manipulación de matriz hará que su función sea mucho más simple:
x <- read.table(text="
lat long
105252 30°25.264 9°01.331
105253 30°39.237 8°10.811
105255 31°37.760 8°06.040
105258 31°41.190 8°06.557
105259 31°41.229 8°06.622
105260 31°38.891 8°06.281",
header=TRUE, stringsAsFactors=FALSE)
x
La propia función hace uso de:
-
strsplit()
con el patrón destrsplit()
regulares"[°//.]"
: esto hace que la cadena se divida en un paso -
sapply
para hacer un bucle sobre el vector
Prueba esto:
convert<-function(x){
z <- sapply((strsplit(x, "[°//.]")), as.numeric)
z[1, ] + z[2, ]/60 + z[3, ]/3600
}
Intentalo:
convert(x$long)
[1] 9.108611 8.391944 8.111111 8.254722 8.272778 8.178056
Descargo de responsabilidad: no revisé sus matemáticas. Utilice a su propia discreción.
Utilice el paquete de medidas de CRAN que ya tiene una función de conversión de unidades, por lo que no necesita hacer su propia:
x = read.table(text = "
lat long
105252 30°25.264 9°01.331
105253 30°39.237 8°10.811
105255 31°37.760 8°06.040
105258 31°41.190 8°06.557
105259 31°41.229 8°06.622
105260 31°38.891 8°06.281",
header = TRUE, stringsAsFactors = FALSE)
Una vez que su data.frame está configurado entonces:
# change the degree symbol to a space
x$lat = gsub(''°'', '' '', x$lat)
x$long = gsub(''°'', '' '', x$long)
# convert from decimal minutes to decimal degrees
x$lat = measurements::conv_unit(x$lat, from = ''deg_dec_min'', to = ''dec_deg'')
x$long = measurements::conv_unit(x$long, from = ''deg_dec_min'', to = ''dec_deg'')
Resultando en el producto final:
lat long
105252 30.4210666666667 9.02218333333333
105253 30.65395 8.18018333333333
105255 31.6293333333333 8.10066666666667
105258 31.6865 8.10928333333333
105259 31.68715 8.11036666666667
105260 31.6481833333333 8.10468333333333