Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If I understand correctly, you can do this simply enough with <code>gDistance</code> in the <code>rgeos</code> package. </p> <p>Read in the lines as <code>SpatialLines/DataFrame</code> and points as <code>SpatialPoints/DataFrame</code> and then loop over each point calculating the distance each time: </p> <pre><code>require(rgeos) ## untested code shortest.dists &lt;- numeric(nrow(sp.pts)) for (i in seq_len(nrow(sp.pts)) { shortest.dists[i] &lt;- gDistance(sp.pts[i,], sp.lns) } </code></pre> <p>Here <code>sp.pts</code> is the Spatial points object, and <code>sp.lns</code> is the Spatial lines object. </p> <p>You must loop so that you only compare a single coordinate in <code>sp.pts</code> with the entirety of all lines geometries in <code>sp.lns</code>, otherwise you get the distance from an aggregate value across all points. </p> <p>Since your data are in latitude/longitude you should transform both the lines and points to a suitable projection since the <code>gDistance</code> function assumes Cartesian distance. </p> <p>MORE DISCUSSION AND EXAMPLE (edit)</p> <p>It would be neat to get the nearest point on the line/s rather than just the distance, but this opens another option which is whether you need the nearest <em>coordinate</em> along a line, or an actual <em>intersection</em> with a line segment that is closer than any existing vertex. If your vertices are dense enough that the difference doesn't matter, then use <code>spDistsN1</code> in the <code>sp</code> package. You'd have to extract all the coordinates from every line in the set (not hard, but a bit ugly) and then loop over each point of interest calculating the distance to the line vertices - then you can find which is the shortest and select that coordinate from the set of vertices, so you can have the distance and the coordinate easily. There's no need to project either since the function can use ellipsoidal distances with <code>longlat = TRUE</code> argument. </p> <pre><code>library(maptools) ## simple global data set, which we coerce to Lines data(wrld_simpl) wrld_lines &lt;- as(wrld_simpl, "SpatialLinesDataFrame") ## get every coordinate as a simple matrix (scary but quick) wrld_coords &lt;- do.call("rbind", lapply(wrld_lines@lines, function(x1) do.call("rbind", lapply(x1@Lines, function(x2) x2@coords[-nrow(x2@coords), ])))) </code></pre> <p>Check it out interactively, you'll have to modify this to save the coords or minimum distances. This will plot up the lines and wait for you to click anywhere in the plot, then it will draw a line from your click to the nearest <em>vertex</em> on a line. </p> <pre><code>## no out of bounds clicking . . . par(mar = c(0, 0, 0, 0), xaxs = "i", yaxs = "i") plot(wrld_lines, asp = "") n &lt;- 5 for (i in seq_len(n)) { xy &lt;- matrix(unlist(locator(1)), ncol = 2) all.dists &lt;- spDistsN1(wrld_coords, xy, longlat = TRUE) min.index &lt;- which.min(all.dists) points(xy, pch = "X") lines(rbind(xy, wrld_coords[min.index, , drop = FALSE]), col = "green", lwd = 2) } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload