Ali Mroueh
Ali Mroueh

Reputation: 33

Checking if coordinate points fall on a line

I have lines (edges) that have a starting lat/lon and an ending lat/lon. I also have a dataframe of many other points and I want to see whether they are on the line or not. For example, the beginning coordinate for my line is lon=-124.1637 and lat=40.80207 and the end is (-122.4199,37.77903). I want to verify if the point (-123.4167,39.50740) falls on the line created by the first two coordinate points. I am really not sure how to go about this. This is according to a projected coordinate system and they the points need to fall exactly on the line.

Upvotes: 0

Views: 507

Answers (2)

ThomasIsCoding
ThomasIsCoding

Reputation: 101247

Maybe you can use approx (linear interpolation) to check if the point is on the line, e.g.,

> approx(df$lon,df$lat,-123.4167)$y==39.50740
[1] FALSE

DATA

df <- structure(list(lon = c(-124.1637, -122.4199), lat = c(40.80207, 
37.77903)), class = "data.frame", row.names = c(NA, -2L))

> df
        lon      lat
1 -124.1637 40.80207
2 -122.4199 37.77903

Upvotes: 2

Brian
Brian

Reputation: 8275

library(sf)
#> Linking to GEOS 3.7.2, GDAL 2.4.2, PROJ 5.2.0
test_line <- st_linestring(
  matrix(
    c(-124.1637, 40.80207, -122.4199, 37.77903), 
    nrow = 2, byrow = T
    )
  ) %>% 
  st_sfc() %>% 
  st_set_crs(4326)

test_pt <- st_point(c(-123.4167, 39.50740)) %>% 
  st_sfc() %>% 
  st_set_crs(4326)

st_intersects(test_pt, test_line)
#> although coordinates are longitude/latitude, st_intersects assumes that they are planar
#> Sparse geometry binary predicate list of length 1, where the predicate was `intersects'
#>  1: (empty)

st_distance(test_pt, test_line)
#> Units: [m]
#>          [,1]
#> [1,] 1583.654

Created on 2020-04-13 by the reprex package (v0.3.0)

Arranging your points and lines into {sf}-geometry dataframes is a prerequisite for using the st_relate functions, but once you have them, it's straightforward to test if they intersect exactly, which they don't (empty set). Also, they will probably not ever, with a point on a line, unless it's one of the exact endpoints.

A smarter way is to test how far the point is from the line, here 1,584 meters, and filter out those that are above some threshhold (100 m? 10 m? 1 m? 0.1 m? Depends on your application).

To illustrate this point, here's a map of your test point and line, with the counties surrounding them. Visually, the point is certainly on the line, but mathematically, it is not.

enter image description here

Upvotes: 1

Related Questions