rterra

How to extend the boundary of polygon until a line?


I have two objects:

eez:https://github.com/yuliaUU/test/blob/main/eez.RDS

bordering_polygons: https://github.com/yuliaUU/test/blob/main/madg_bordering_polygons.RData

So what I want to do is to try to extend the outer boundary of each bordering_polygons untill eez line, and so that boundaries will not overlap

As suggested , i tried teh following:

v <- vect(bordering_polygons)
r <- rast(eez, res=.1)
# get the distance to each polygon, and then find the nearest polygon
rr <- lapply(1:nrow(v), \(i) distance(r, v[i])) |> rast() |> which.min()

z <- erase(as.polygons(rr), v)
values(z) <- values(v)[unlist(z[[1]]),  ]
x <- rbind(v, z)
a <- aggregate(x, names(x))
plot(v)
plot(a, "ADM1_EN", type="classes")
lines(v, lwd=3, col="gray")
lines(eez, col="red", lwd=3)

[1]: https://i.sstatic.net/QSvwq8nZ.png

my only issue that the created areas are not combined with existing polygons


Solution

  • The tricky bit is to extend polygons. Here is an approach that uses a (discrete) raster.

    Example data (please do not ask questions based on files that need to be downloaded)

    library(terra)
    # your island 
    v <- vect(system.file("ex/lux.shp", package="terra"))
    # use planar crs to speed things up
    vcrs <- crs(v)
    crs(v) <- "local"
    # example EEZ
    e <- as.polygons(ext(v) + .05, crs=crs(v)) 
    

    Define a raster (higher resolution is better, but slower)

    r <- rast(e, res=.01)
    # get the distance to each polygon, and then find the nearest polygon
    rr <- lapply(1:nrow(v), \(i) distance(r, v[i])) |> rast() |> which.min()
    

    Create polygons, erase what we already have, set the attributes and combine with the admin areas of the island.

    z <- erase(as.polygons(rr), v)
    values(z) <- values(v)[unlist(z[[1]]),  ]
    x <- rbind(v, z)
    a <- aggregate(x, names(x))
    crs(a) <- vcrs
    

    Illustration of the result

    plot(a, "ID_2", type="classes")
    lines(v, lwd=3, col="gray")
    lines(e, col="red", lwd=3)
    

    enter image description here

    For your data you need some minor adjustments (because the island has a hole and the outside boundary is not rectangular.

    eez <- vect(eez)
    mdg <- vect(bordering_polygons)
    mcrs <- crs(mdg)
    crs(eez) <- crs(mdg) <- "local"
    
    r <- rast(eez, res=.1)
    rr <- lapply(1:nrow(mdg), \(i) distance(r, mdg[i])) |> rast() |> which.min()
    
    fmdg <- aggregate(mdg) |> fillHoles()
    z <- erase(as.polygons(rr), fmdg)
    values(eez) <- NULL
    z <- intersect(z, eez)
    values(z) <- values(mdg)[unlist(z[[1]]), ,drop=FALSE]
    x <- rbind(mdg, z)
    x <- aggregate(x, names(x))
    crs(x) <- mcrs
    
    plot(x, "ADM1_EN", type="classes")
    lines(mdg, lwd=3, col="gray")
    lines(eez, col="red", lwd=3)
    

    enter image description here