Search code examples
rsortinggeospatialspatial

How do I sort points in clockwise order in R with respect to the center?


I have a dataset with the X and Y coordinates and I am trying to figure out a way to sort them in clockwise (or Anticlockwise) direction in R from the center. Assuming the median of latitude and longitude as the center.

The sample data:

df <- structure(list(name = c("A", "B", "C", "D", "E", "F", "G", "H", 
                              "I", "J"), lat = c(22.57, 22.69, 22.72, 22.5, 22.66, 22.19, 22.6, 
                                                 22.27, 22.31, 22.15), lon = c(88.69, 88.84, 88.77, 88.85, 88.63, 
                                                                               88.91, 88.54, 88.62, 88.78, 88.66)), class = "data.frame", row.names = c(NA, 
                                                                                                                                                        -10L))

The points

What I am looking for is say, the points from the above image can be sorted like this: G -> E -> A-> C -> B and so on.

So far, I have tried calculating the polar position with arc tan function and then sort them but that didn't yield a good result.

I have also tried the orderPoints function, but the ordering has been doubtful there too. The order I got was something like this: D-> F-> G-> B-> H-> J-> I-> E-> C-> A. While some of them seem to be in order, others are looking far off.


Solution

  • (As @thelatemail indicated, the answer will depend on which point is assumed to be the center around which the points are arranged. The approach below takes a point near the median point, chosen to provide the order you expected. The actual median point will indicate A before E.)

    df$angle = atan2(df$lat - 22.5,
                     df$lon - 88.68)
    library(ggplot2)
    ggplot(df[order(df$angle, decreasing = TRUE), ], 
           aes(lon, lat, color = angle, label = name)) +
      geom_path(arrow = arrow(type = "closed", length = unit(0.05, "npc"))) + 
      geom_text(size = 8, color = "black") +
      annotate("point", x = 88.68, y = 22.5, color = "red")
    

    enter image description here