Converting geo coordinates from degree to decimal

后端 未结 7 880
滥情空心
滥情空心 2020-11-28 10:48

I want to convert my geographic coordinates from degrees to decimals, my data are as follows:

         lat     long
105252 30°25.264 9°01.331
105253 30°39.23         


        
相关标签:
7条回答
  • 2020-11-28 11:03

    Try using the char2dms function in the sp library. It has other functions that will additionally do decimal conversion.

    library("sp")
    ?char2dms
    
    0 讨论(0)
  • 2020-11-28 11:05

    As Jim Lewis commented before it seems your are using floating point minutes. Then you only concatenate two elements on

    dec=c(as.numeric(tmp1[[1]][1]),as.numeric(tmp2[[1]]))

    Having degrees, minutes and seconds in the form 43°21'8.02 which as.character() returns "43°21'8.02\"", I updated your function to

    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)
    }
    

    adding the alternative for negative coordinates, and works great for me . I still don't get why char2dms function in the sp library didn't work for me.

    Thanks

    0 讨论(0)
  • 2020-11-28 11:06

    Thanks for answers by @Gord Stephen and @CephBirk. Sure helped me out. I thought I'd just mention that I also found that measurements::conv_unit doesn't deal with "E/W" "N/S" entries, it requires positive/negative degrees. My coordinates comes as character strings "1 1 1W" and needs to first be converted to "-1 1 1".
    I thought I'd share my solution for that.

    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
    
    0 讨论(0)
  • 2020-11-28 11:09

    Have a look at the command degree in the package OSMscale.

    0 讨论(0)
  • 2020-11-28 11:11

    A bit of vectorization and matrix manipulation will make your function much simpler:

    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
    

    The function itself makes use of:

    • strsplit() with the regex pattern "[°\\.]" - this does the string split in one step
    • sapply to loop over the vector

    Try this:

    convert<-function(x){
      z <- sapply((strsplit(x, "[°\\.]")), as.numeric)
      z[1, ] + z[2, ]/60 + z[3, ]/3600
    } 
    

    Try it:

    convert(x$long)
    [1] 9.108611 8.391944 8.111111 8.254722 8.272778 8.178056
    

    Disclaimer: I didn't check your math. Use at your own discretion.

    0 讨论(0)
  • 2020-11-28 11:21

    Another less elegant option using substring instead of strsplit. This will only work if all your positions have the same number of digits. For negative co-ordinates just multiply by -1 for the correct decimal degree.

    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))
    
    0 讨论(0)
提交回复
热议问题