Search code examples
ralgorithmpolygonggmap

R: Polygon combining Algorithm


I have a file with different polygons, defined as a data.frame with an id, lng and lat. With the following code I can plot these polygons on a map.

    library(ggmap)
    library(ggplot2)

    map <- get_googlemap(center = c(lon = 9.26, lat = 47.3), zoom=10)
    xy <- data.frame(id = c(rep(1,4), rep(2,4)), lng = c(9,9.5,9.5,9,9.25,9.7,9.7,9.24), lat= c(47.1,47.1,47.4,47.4,47.2,47.2,47.5,47.5))
    p <- ggmap(map) + geom_polygon(data=xy, aes(x=xy$lng, y=xy$lat,group=xy$id),fill='red',alpha= 0.2)
    print(p)

Is there a function to merge polygons before I plot them? I want to plot one polygon which covers everything that's under at least one of the polygons. Therefore I need to create new points at intersections and the convex hull won't cut.


Solution

  • If you mean:

    I want to plot one polygon which covers everything that's under AT LEAST one of the polygons.

    then chull (convex hull) might be what you are after.

    As an example (not ggplot though):

    # create data: (x,y)-coords
    x<-c(1:9,9:1)
    y<-runif(length(x))*10
    # plot `em
    plot(x,y,type="l")
    # these are the indexes of points that are the convex hull
    print(chull(x,y))
    these.idx<-chull(x,y)
    # plot the convex hull using the indexes
    lines(x[these.idx],y[these.idx],type="l",col="red",lwd=2)
    

    For your ggplot scenario, if your code is modified like below it plots a single polygon (although it's hard to know whether that's what you are after):

    library(ggmap)
    library(ggplot2)
    
    map <- get_googlemap(center = c(lon = 9.26, lat = 47.3), zoom=10)
    xy <- data.frame(id = c(rep(1,4), rep(2,4))
        , lng = c(9,9.5,9.5,9,9.25,9.7,9.7,9.24)
        , lat= c(47.1,47.1,47.4,47.4,47.2,47.2,47.5,47.5))
    ch.idx<-chull(xy$lng,xy$lat)
    xy<-xy[ch.idx,]
    # removing:: ,group=xy$id
    p <- ggmap(map) 
    p <- p + geom_polygon(data=xy, aes(x=xy$lng, y=xy$lat),fill='red',alpha= 0.2)
    print(p)
    

    (This is more a comment not an answer but I don't have the 'rep' to do that sorry)