Too simple right now. Needs real world distances.

library(curl)
library(ggplot2)
library(raster)
library(rgdal)
library(rgeos)
library(RColorBrewer)
library(rgl)
library(sp)
library(spatstat)

There is a fairly lo-rez Mediterranean outline at http://worldmap.harvard.edu/data/geonode:mediterraneansea_q5m . But good enough to demo buffering.

readOGR("http://worldmap.harvard.edu/download/wfs/20669/json?outputFormat=json&service=WFS&request=GetFeature&format_options=charset%3AUTF-8&typename=geonode%3Amediterraneansea_q5m&version=1.0.0", layer="OGRGeoJSON", disambiguateFIDs = T) -> medoutline.sp
## OGR data source with driver: GeoJSON 
## Source: "http://worldmap.harvard.edu/download/wfs/20669/json?outputFormat=json&service=WFS&request=GetFeature&format_options=charset%3AUTF-8&typename=geonode%3Amediterraneansea_q5m&version=1.0.0", layer: "OGRGeoJSON"
## with 1 features and 8 fields
## Feature type: wkbPolygon with 2 dimensions
plot(medoutline.sp, col = 'blue')

# this will load four maps from http://awmc.unc.edu/ .
# It's a cheap way of getting those and I really should make a package
load(curl("https://gist.githubusercontent.com/sfsheath/51b4565d843d9a057a43/raw/awmc.RData"))

#plot Roman empire to confirm load
par(mai=c(0,0,0,0))
plot(awmc.roman.empire.200.sp)

# load amphitheater data
ramphs <- read.csv(curl("https://gist.githubusercontent.com/sfsheath/4324b4505f1952b930ba/raw/f89e55ed6a73e17832f48192bfd89d1d055d5285/roman-amphitheaters.csv"))
ramphs.sp <- ramphs
coordinates(ramphs.sp) <- ~longitude+latitude
proj4string(ramphs.sp)=CRS("+proj=longlat +datum=WGS84")

# plot everything to show that all are reasonably well aligned
par(mai = c(0,0,0,0)) # no margins
plot(ramphs.sp, col = "red")
plot(medoutline.sp, col = "blue", add = T)
plot(awmc.roman.empire.200.sp, add = T)

gBuffer(medoutline.sp, width = 2) ->  medbuffer.sp
## Warning in gBuffer(medoutline.sp, width = 2): Spatial object is not
## projected; GEOS expects planar coordinates
plot(medbuffer.sp, col = "green")

plot(awmc.roman.empire.200.sp, col = "red")
plot(medbuffer.sp, col = "green", add = T)
plot(medoutline.sp, col = "blue", add = T)

spTransform(medbuffer.sp, CRS(proj4string(ramphs.sp))) -> tmp.sp # they differ only in detail but seems still necessary
sp::over(ramphs.sp,tmp.sp) -> these.ramphs
ramphs.sp[!is.na(these.ramphs),] -> these.ramphs.sp
ramphs.sp[is.na(these.ramphs),] -> not.these.ramphs.sp

par(mai= c(0,0,0,0))
plot(awmc.roman.empire.200.sp, col = "red")
plot(medbuffer.sp, col = "green", add = T)
plot(medoutline.sp, col = "blue", add = T)
plot(these.ramphs.sp, col = "yellow", add = T)
plot(not.these.ramphs.sp, col = "black", add = T)

Yeah, that’s pretty ugly…