计算两条线之间的最宽距离
Calculate widest distance between two lines
我想计算平均距离以及两条线之间的最宽距离。我知道如何使用 st_distance() 函数找到最小距离,但我不确定如何找到其他两个指标。红线是我认为我需要测量以找到两条线之间的平均距离和最宽距离的线。
附件是一些示例数据。
pts1<- data.frame(
x= c(-103.485342, -103.482808),
y = c(31.348758, 31.376947))
) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts1)<- "+init=epsg:2257"
pts2<- data.frame(
x= c(-103.492822, -103.484231),
y = c(31.348181, 31.377191))
) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts2)<- "+init=epsg:2257"
a <- pts1 %>% st_coordinates() %>% st_linestring()
b<- pts2 %>% st_coordinates() %>% st_linestring()
min_dist<-st_distance(a,b,by_element = T)
见下面的第二个例子。从图像中我计算出距离垂直线约 300 米,垂直线最大程度地穿过两条线。
pts1 <- data.frame(x = c(-103.485342, -103.482808),
y = c(31.348758, 31.376947)) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts1) <- "+proj=longlat +datum=WGS84"
pts1<- st_transform(pts1,"+init=epsg:2257")
pts2 <- data.frame(x = c(-103.492812, -103.484231),
y = c(31.318181, 31.377991)) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts2) <- "+proj=longlat +datum=WGS84"
pts2<- st_transform(pts2,"+init=epsg:2257")
a <- pts1 %>% st_coordinates() %>% st_linestring()
b <- pts2 %>% st_coordinates() %>% st_linestring()
st_distance(pts1, pts2, by_element = T)
我给你一个见解,也许这不是你想象的完整答案。
由于线是由点组成的,如果你只做两个轻微的改变,你不仅可以有最小距离,还可以通过做与线相同的事情来获得最大距离,但是点包含行。
library(sf)
#> Linking to GEOS 3.8.0, GDAL 2.4.2, PROJ 6.2.1
pts1 <- data.frame(x = c(-103.485342, -103.482808),
y = c(31.348758, 31.376947)) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts1) <- "+init=epsg:2257"
pts2 <- data.frame(x = c(-103.492822, -103.484231),
y = c(31.348181, 31.377191)) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts2)<- "+init=epsg:2257"
a <- pts1 %>% st_coordinates() %>% st_linestring()
b <- pts2 %>% st_coordinates() %>% st_linestring()
st_distance(pts1, pts2, by_element = T)
#> Units: [US_survey_foot]
#> [1] 0.007502222 0.001443768
对于平均距离,我不确定这是否是你想要的,但我认为你可以获得两条线的质心然后处理st_distance
。
ca <- st_centroid(a)
cb <- st_centroid(b)
st_distance(ca, cb, by_element = T)
#> [1] 0.004454613
编辑:我最后一次尝试基于评论
我认为如果找到最长的线(在您的示例中为 b),而不是处理并找到较短线的点与最长线本身之间的最长距离,您可能会得到想要的东西:
(我还对您的原始代码进行了一些更改以使其有效)
library(sf)
pts1 <- data.frame(x = c(-103.485342, -103.482808),
y = c(31.348758, 31.376947)) %>%
st_as_sf(coords = c("x","y")) %>%
st_set_crs(4326) %>%
st_transform(2257)
pts2 <- data.frame(x = c(-103.492812, -103.484231),
y = c(31.318181, 31.377991)) %>%
st_as_sf(coords = c("x","y")) %>%
st_set_crs(4326) %>%
st_transform(2257)
a <- pts1 %>%
st_union(.) %>%
st_cast(to = "LINESTRING")
b <- pts2 %>%
st_union(.) %>%
st_cast(to = "LINESTRING")
longest <- ifelse(test = st_length(a) > st_length(b),
yes = quote(a),
no = quote(b))
max(st_distance(pts1, eval(longest)))
#> 955.7374 [US_survey_foot]
我想计算平均距离以及两条线之间的最宽距离。我知道如何使用 st_distance() 函数找到最小距离,但我不确定如何找到其他两个指标。红线是我认为我需要测量以找到两条线之间的平均距离和最宽距离的线。
附件是一些示例数据。
pts1<- data.frame(
x= c(-103.485342, -103.482808),
y = c(31.348758, 31.376947))
) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts1)<- "+init=epsg:2257"
pts2<- data.frame(
x= c(-103.492822, -103.484231),
y = c(31.348181, 31.377191))
) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts2)<- "+init=epsg:2257"
a <- pts1 %>% st_coordinates() %>% st_linestring()
b<- pts2 %>% st_coordinates() %>% st_linestring()
min_dist<-st_distance(a,b,by_element = T)
见下面的第二个例子。从图像中我计算出距离垂直线约 300 米,垂直线最大程度地穿过两条线。
pts1 <- data.frame(x = c(-103.485342, -103.482808),
y = c(31.348758, 31.376947)) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts1) <- "+proj=longlat +datum=WGS84"
pts1<- st_transform(pts1,"+init=epsg:2257")
pts2 <- data.frame(x = c(-103.492812, -103.484231),
y = c(31.318181, 31.377991)) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts2) <- "+proj=longlat +datum=WGS84"
pts2<- st_transform(pts2,"+init=epsg:2257")
a <- pts1 %>% st_coordinates() %>% st_linestring()
b <- pts2 %>% st_coordinates() %>% st_linestring()
st_distance(pts1, pts2, by_element = T)
我给你一个见解,也许这不是你想象的完整答案。
由于线是由点组成的,如果你只做两个轻微的改变,你不仅可以有最小距离,还可以通过做与线相同的事情来获得最大距离,但是点包含行。
library(sf)
#> Linking to GEOS 3.8.0, GDAL 2.4.2, PROJ 6.2.1
pts1 <- data.frame(x = c(-103.485342, -103.482808),
y = c(31.348758, 31.376947)) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts1) <- "+init=epsg:2257"
pts2 <- data.frame(x = c(-103.492822, -103.484231),
y = c(31.348181, 31.377191)) %>%
sf::st_as_sf(coords = c("x","y"))
st_crs(pts2)<- "+init=epsg:2257"
a <- pts1 %>% st_coordinates() %>% st_linestring()
b <- pts2 %>% st_coordinates() %>% st_linestring()
st_distance(pts1, pts2, by_element = T)
#> Units: [US_survey_foot]
#> [1] 0.007502222 0.001443768
对于平均距离,我不确定这是否是你想要的,但我认为你可以获得两条线的质心然后处理st_distance
。
ca <- st_centroid(a)
cb <- st_centroid(b)
st_distance(ca, cb, by_element = T)
#> [1] 0.004454613
编辑:我最后一次尝试基于评论
我认为如果找到最长的线(在您的示例中为 b),而不是处理并找到较短线的点与最长线本身之间的最长距离,您可能会得到想要的东西:
(我还对您的原始代码进行了一些更改以使其有效)
library(sf)
pts1 <- data.frame(x = c(-103.485342, -103.482808),
y = c(31.348758, 31.376947)) %>%
st_as_sf(coords = c("x","y")) %>%
st_set_crs(4326) %>%
st_transform(2257)
pts2 <- data.frame(x = c(-103.492812, -103.484231),
y = c(31.318181, 31.377991)) %>%
st_as_sf(coords = c("x","y")) %>%
st_set_crs(4326) %>%
st_transform(2257)
a <- pts1 %>%
st_union(.) %>%
st_cast(to = "LINESTRING")
b <- pts2 %>%
st_union(.) %>%
st_cast(to = "LINESTRING")
longest <- ifelse(test = st_length(a) > st_length(b),
yes = quote(a),
no = quote(b))
max(st_distance(pts1, eval(longest)))
#> 955.7374 [US_survey_foot]