I have multiple points (lon, lat) for a range of countries. These points are related by an ID that when connected creates a line.
data exmaple:
aus:
id country point_id lon lat
1 Australia 0 130.1491 -19.57520
1 Australia 1 129.9958 -19.48760
1 Australia 2 129.7156 -19.25788
1 Australia 3 129.7104 -19.20223
2 Australia 0 129.2510 -18.59016
2 Australia 1 129.5436 -18.30723
3 Australia 0 137.2840 -20.06129
3 Australia 1 137.2865 -20.04308
3 Australia 2 137.1915 -20.00782
3 Australia 3 137.1220 -19.97166
3 Australia 4 137.0650 -19.91363
3 Australia 5 136.8961 -19.85932
4 Australia 0 136.8961 -19.85932
4 Australia 1 136.8791 -19.88669
4 Australia 2 136.8594 -19.91227
4 Australia 3 136.8454 -19.92507
4 Australia 4 136.8360 -19.92976
I managed to create the geometry following this post [1], however, I think my attempt can be automated further. I attempted using group by individually, as follow:
attempt 1 to get linestrings:
# same logic as in [1] but by group
aus_group <- aus %>% group_by(id, country)
b_group <- aus %>% group_by(id, country) %>% select(lon, lat)
e_group <- aus %>% group_by(id, country) %>% filter(row_number()!=1) %>% select(lon, lat)
f_group <- e_group %>% group_by(id, country) %>% summarise_all(last) %>% select(country, lon, lat)
g_group <- e_group %>% group_by(id, country) %>% rbind(f_group) %>% arrange(id)
aus_group$geometry = do.call(
"c",
lapply(seq(nrow(b_group)), function(i) {
st_sfc(
st_linestring(
as.matrix(
rbind(b_group[i, c("lon", "lat")], g_group[i, c("lon", "lat")])
)
),
crs = 4326
)
}))
dat_g_sf = st_as_sf(aus_group)
mapview(dat_g_sf, zcol = "id")
# to compare with approach in [1]
dat_g_sf %>% filter(id==1) %>% mapview(zcol = "point_id") # got same plot
# so it works
I share this part in case there are suggestions to improve the group_by part
question:
My actual question is regarding distance estimation between points and the relative elevation between those points.
For the distance estimation, I have tried this:
attempt 2 to get distances:
# edited aus_1 becomes aus
aus_2 <- aus %>% select(id, country, point_id, lon, lat) #to avoid error with geometry
str(aus_2)
aus_2$distance = do.call(
"c",
lapply(seq(nrow(b)), function(i) {
st_distance(
st_sfc(st_point
# edited b becomes b_group, and g becomes g_group
(as.matrix(rbind(b_group[i, c("lon", "lat")], g_group[i, c("lon", "lat")], by_element = TRUE)
)
),
crs = 4326
)
}))
Error in st_point(as.matrix(rbind(b_group[i, c("lon", "lat")], g_group[i, c("lon", "lat")]), by_element = TRUE)) :
nrow(x) == 1 is not TRUE
I think the error might be related with the matrix creation. I appreciate any help here.
expected results: edited.
As can be seen in my attempt 2, I tried to get the length between points (by point_id), e.g., distance between point_id: 0 & 1, in id: 1; and so on; using st_distance. (I guess the sum of all distances by point_id would result on the total length estimation).
In my understanding, the distance for point_id == 0 should be zero because it is the distance between point_id: 0 and 0, while the distance between point_id: 0 and 1 is the actual distance for point_id: 1. This is the reason why in my attempt 1 and 2, I tried to create two groups of c("lon", "lat"): b_group and g_group, and then I try applying st_distance between point b and point g. Unfortunately, this did not work.
Overall: it is expected "an sf object of point geometries with the same number of rows as an input dataset, with distance to lagging or leading point (between point_id) within the same group (id) + elevation (between by point_id)" from margusl comment.
no edited:
For the relative elevation estimation, I haven’t found previous work on this using R. Suggestions regarding where to start about elevation estimation are welcome.
Also, what is the meaning of "c" in 1? How does it work in the function?
For elevation you'd need some data source / provider.
elevatrpackage potentially can provide you values for point locations, for example through Amazon Web Service Terrain Tiles, but you'd probably need to evaluate those results and work out acceptable resolution / zoom levels,elevatrdocs should cover this part.To get distances between every current and previous point, you can use element-wise distance with lag:
Dataset example:
Original answer - https://stackoverflow.com/revisions/78251444/1