将一个lonlat向量标定为一定长度,单位为米。

问题描述 投票:0回答:1

我有一些GPS测量的线,每条线有3个点,由于测量的不确定性,这些线是歪的,我想用长度正好为 50m 以被测线的中心点为中心,以被测点的大方向为中心。

要做到这一点,我想去 25m 从中心点(由lon lat坐标给出)向某一方向,由lon lat向量给出。现在的问题是,在不同的纬度上。25m 的度数是不一样的。我做了一些计算,得到1m在该位置的长度(度数)。

# Calculate the length of a 1 degree difference
earth_circumference <- 40075016.7
for(i in 1:nrow(coords)){
  coords$d_m_lon[i] <- earth_circumference/360*cos(abs(coords$c_lat[1])*pi/180)
  coords$d_m_lat[i] <- earth_circumference/360
}

# Claculate the difference in degree that 1m at the surface makes
coords$m_d_lon <- 1/coords$d_m_lon
coords$m_d_lat <- 1/coords$d_m_lat

我有一个 数据框 (协约),它的每一行都包含了起点的坐标。s,中心 c 终止 e 点的一条线。我做了一个回归,得到最接近点的大方向的线(这里,我用的是 [1] 的第一行数据;如果它有效,显然将循环重复所有行的过程)。)

# Calculate average transect directions
points <- data.frame(
  x = c(coords$s_lon[1], coords$c_lon[1], coords$e_lon[1]),
  y = c(coords$s_lat[1], coords$c_lat[1], coords$e_lat[1])
)
mod <- lm(points$y ~ points$x)
a <- coefficients(mod)[1]
b <- coefficients(mod)[2]

现在,我试着按照模型给出的方向去做,并且不惜一切代价地缩放矢量,使它成为 25m 在给定的纬度上,长,但不知何故,新。开始结束 点都不在回归线上了。

center <- c(coords$c_lon[1], coords$c_lat[1])
direction <- c(b-a, 1)/sqrt((b-a)^2 + 1)

start <- center + 25*c(coords$m_d_lon[1], coords$m_d_lat[1])*direction
end <- center - 25*c(coords$m_d_lon[1], coords$m_d_lat[1])*direction

有谁知道错误在哪里 或者知道如何解决这个问题?我想是我没有正确地缩放向量...

以防你要第一条线的数据来测试这个问题。

coords <- structure(list(s_lat = -29.6032, s_lon = 29.3376, c_lat = -29.6032, 
    c_lon = 29.3379, e_lat = -29.6032, e_lon = 29.3381, d_m_lon = 96788.6617220582, 
    d_m_lat = 111319.490833333, m_d_lon = 1.03317886848321e-05, 
    m_d_lat = 8.98315283796251e-06), row.names = 1L, class = "data.frame")
r vector geospatial latitude-longitude
1个回答
2
投票

我不知道你想要什么格式的输出,但这可能会让你开始... ...

结果是两个新的列。new_snew_e,格式为long,lat - 。

library( tidyverse )  
library( geosphere )

coords <- coords %>%
  #calculate bearing from center ppint to s-point
  mutate( bearing_c_to_s = pmap( list ( a = c_lon,
                                        b = c_lat,
                                        x = s_lon,
                                        y = s_lat ),
                                 ~ geosphere::bearing( c(..1, ..2), c(..3, ..4) ) 
                                 )
          ) %>%
  #calculate bearing from center ppint to s-point
  mutate( bearing_c_to_e = pmap( list ( a = c_lon,
                                        b = c_lat,
                                        x = e_lon,
                                        y = e_lat ),
                                 ~ geosphere::bearing( c(..1, ..2), c(..3, ..4) )  
                                 )
          ) %>%
  #calculate new point s coordinates, 25 meters from c using bearing c_to_s
  mutate( new_s = pmap( list ( a = c_lon,
                               b = c_lat,
                               x = bearing_c_to_s,
                               y = 25 ),
                        ~ geosphere::destPoint( c(..1, ..2), ..3, ..4 ) 
                        )
          ) %>%
  #calculate new point e coordinates, 25 meters from c using bearing c_to_e
  mutate( new_e = pmap( list ( a = c_lon,
                               b = c_lat,
                               x = bearing_c_to_e,
                               y = 25 ),
                        ~ geosphere::destPoint( c(..1, ..2), ..3, ..4 ) 
                        )
  )

在地图上输出

library( sf )
library( data.table )
setDT(coords)
coords_old <- data.table::melt(coords, measure.vars = patterns( lat = "^[a-z]_lat", lon = "^[a-z]_lon" ) )[, c("lon","lat")]
coords_old <- sf::st_as_sf( coords_old, coords = c("lon", "lat"), crs = 4326 )
coords[, c("new_s_lon", "new_s_lat") := ( as.list( unlist( new_s ) ) ) ]
coords[, c("new_e_lon", "new_e_lat") := ( as.list( unlist( new_e ) ) ) ]
coords_new <- data.table::melt(coords, measure.vars = patterns( lat = "^(c|new_[se])_lat", lon = "^(c|new_[se])_lon" ) )[, c("lon","lat")]
coords_new <- sf::st_as_sf( coords_new, coords = c("lon", "lat"), crs = 4326 )

library( leaflet )
leaflet() %>% 
  addTiles() %>% 
  addCircleMarkers( data = coords_old, color = "red" ) %>%
  addCircleMarkers( data = coords_new, color = "blue" )

旧的点是红色的,新的点是蓝色的......中心点保持不变......。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.