I am trying to calculate distance of points within a country to country boundary
library(terra)
library(geodata)
library(ggplot2)
library(geodata)
# get a shapefile of a country
gabon <- geodata::gadm('GAB', level = 0, path = getwd())
canvas <- terra::rast(xmin = ext(gabon)[1],
xmax = ext(gabon)[2],
ymin = ext(gabon)[3],
ymax = ext(gabon)[4],
resolution = 0.08,
crs = crs(gabon),
vals = 0)
pts <- as.points(canvas)
pts <- terra::crop(pts, gabon) # extract the points in the limits of Gabon
plot(pts)
plot(gabon, border = "blue", add = T)
I want to calculate shortest distance of each point in pts to the boundary of the country
gabon_lines <- terra::as.lines(gabon)
# calculation of the distance between the boundary and points
dis_pts <- terra::distance(pts, gabon_lines, pairwise = FALSE, unit="km")
range(dis_pts)
# 0.00000046 1.63706213. seems quite low
dat <- data.frame(dist = as.vector(dis_pts),
crds(pts))
col_dist <- brewer.pal(11, "RdGy")
ggplot(dat, aes(x, y, fill = dist)) + #variables
geom_tile() + #geometry
scale_fill_gradientn(colours = rev(col_dist))+ # colors for plotting the distance
labs(fill = "Distance (km)")+ #legend name
theme_void()+ #map theme
theme(legend.position = "bottom") #legend position
I think the range of distance I am getting is very low since Gabon is quite big so I was expecting
distance of points in the middle to be larger. Is there anything I am doing wrong here?
The problem seems to be with the crs used. The result you have above is accurate, but the units are in degrees (latitude & longitude). A relatively quick fix is to reproject the data using crs 5223.
Most of the code below is copied, changes are below ####
library(terra)
library(geodata)
library(ggplot2)
library(scales)
library(RColorBrewer)
# get a shapefile of a country
gabon <- geodata::gadm('GAB', level = 0, path = getwd())
canvas <- terra::rast(xmin = ext(gabon)[1],
xmax = ext(gabon)[2],
ymin = ext(gabon)[3],
ymax = ext(gabon)[4],
resolution = 0.08,
crs = crs(gabon),
vals = 0)
pts <- as.points(canvas)
pts <- terra::crop(pts, gabon) # extract the points in the limits of Gabon
plot(pts)
plot(gabon, border = "blue", add = T)
gabon_lines <- terra::as.lines(gabon)
####
# reproject pts & gabon lines to this new crs:
new_crs <- "+proj=tmerc +lat_0=0 +lon_0=12 +k=0.9996 +x_0=500000 +y_0=500000 +datum=WGS84 +units=m +no_defs +type=crs"
pts2 <- terra::project(pts, new_crs)
gabon_lines2 <- terra::project(gabon_lines, new_crs)
# calculation of the distance between the boundary and points
dis_pts <- terra::distance(pts2, gabon_lines2, pairwise = FALSE, unit="km")
range(dis_pts)
## Now from 1 to about 180 km
## a quick check on google maps & the interior of Gabon is ~180km from the nearest border
dat <- data.frame(dist = as.vector(dis_pts),
crds(pts))
col_dist <- brewer.pal(11, "RdGy")
## Not much change from the plot before, but lat & lon degrees are approximately the same near the equator
ggplot(dat, aes(x, y, fill = dist)) + #variables
geom_tile() + #geometry
scale_fill_gradientn(colours = rev(col_dist))+ # colors for plotting the distance
labs(fill = "Distance (km)")+ #legend name
theme_void()+ #map theme
theme(legend.position = "bottom") #legend position
The dimensions come out a little wonky since the plot isn't using a crs. Changing the data to sf points makes things look a little better:
library(sf)
st_as_sf(dat, coords = c("x", "y")) %>%
ggplot() +
geom_sf(aes(color = dist)) +
scale_color_gradientn(colours = rev(col_dist))
That needs to be fixed, but you can do this
library(terra)
library(geodata)
# get a shapefile of a country
gabon <- geodata::gadm('GAB', level = 0, path = getwd())
canvas <- terra::rast(gabon, resolution = 0.08, vals=0)
m <- mask(canvas, gabon, inverse=TRUE)
d <- distance(m)
plot(d)
Related
In my example, I have:
# Packages
library(sf)
library(ggplot2)
# Create some points
set.seed(1)
df <- data.frame(
gr = c(rep("a",5),rep("b",5)),
x = rnorm(10),
y = rnorm(10)
)
df <- st_as_sf(df,coords = c("x","y"),remove = F, crs = 4326)
df.laea = st_transform(
df,
crs = "+proj=laea +x_0=4600000 +y_0=4600000 +lon_0=0.13 +lat_0=0.24 +datum=WGS84 +units=m"
)
# Create a countour of the area
ch <- st_convex_hull(st_union(df.laea))
ggplot() +
geom_sf(data = ch, fill = "white", color = "black") +
geom_sf(data = df.laea,color = "black")
Now, I'd like to create 10 random points but the conditions are that this points must be inside the ch boundaries and a minimum distance of 10 meters of each df.laea points that exist inside this ch area.
Please, any help with it?
I think the only tricky thing here is that a simple st_difference() of your polygon and the buffered points will return ten polygons, each with one of the points removed. Thus you have to either use a for loop or reduce() to remove one buffered point after the other from the polygon. To use reduce() you have to transform the vector to a proper list of sf instead of an sfc vector. This is what I did below.
# Packages
library(sf)
library(ggplot2)
library(purrr)
ch_minus <- df.laea$geometry |>
st_buffer(10000) |>
{\(vec) map(seq_along(vec), \(x) vec[x])}() |> # Transform buffered points to reducible list
reduce(.init = ch, st_difference)
sampled_points <- st_sample(ch_minus, 10)
ch_minus |>
ggplot() +
geom_sf() +
geom_sf(data = sampled_points)
You can buffer the points by the distance you'd like, then intersect those polygons with the ch polygon. From there, use st_sample and the associated arguments to get the points you want.
Example code:
## buffer df.laea 10m
laea_buff <- st_buffer(df.laea, dist = 10000) #changed dist to 10km to make it noticable in plot
# area to sample from:
sample_area <- st_intersection(ch, laea_buff)
# sample above area, all within 10km of a point and inside the `ch` polygon
points <- st_sample(sample_area, size = 10)
#plotting:
ggplot() +
geom_sf(data = points, color = 'red') +
geom_sf(data = laea_buff, color = 'black', fill = NA) +
geom_sf(data = ch, color = 'black', fill = NA) +
geom_sf(data = sample_area, color = 'pink', fill = NA) +
geom_sf(data = df.laea, color = 'black', size = .5)
Created on 2023-02-14 by the reprex package (v2.0.1)
As a comment on the nice answer by shs: it is possible to first use a sf::st_combine() call on the df.laea object & merge the 10 points to a single multipoint geometry.
This, when buffered, will work as an input for the necessary sf::st_difference() call to form a sampling area with holes, removing the need for a for cycle / map & reduce call.
# Packages
library(sf)
library(ggplot2)
# Create some points
set.seed(1)
df <- data.frame(
gr = c(rep("a",5),rep("b",5)),
x = rnorm(10),
y = rnorm(10)
)
df <- st_as_sf(df,coords = c("x","y"),remove = F, crs = 4326)
df.laea = st_transform(
df,
crs = "+proj=laea +x_0=4600000 +y_0=4600000 +lon_0=0.13 +lat_0=0.24 +datum=WGS84 +units=m"
)
# merge 10 points to 1 multipoing
mod_laea <- df.laea %>%
st_combine()
# sampling area = difference between hull and buffered points
sampling_area <- mod_laea %>%
st_convex_hull() %>%
st_difference(st_buffer(mod_laea, 10000))
# sample over sampling area
sampled_points <- st_sample(sampling_area, 10)
# a visual overview
ggplot() +
geom_sf(data = sampling_area, fill = "white", color = "black") +
geom_sf(data = df.laea, color = "black") +
geom_sf(data = sampled_points, color = "red", pch = 4)
I want to produce a 2d-density plot based on spatial point data. In the background I want to show an open map (e.g. stamen terrain). Besides I want to plot the borders of Austria. Both datasets (data points and border) are shapefiles in EPSG 4326.
I managed to produce such a plot (see screenshots and code V1 below), but the problem is that there is a shift between the map in the background on the one side and the plotted points and the borders of Austria on the other side, as you can see below.
2D-Density Plot V1 - full
2D-Density Plot V1 - detail
Here is the code (V1):
library(sf)
library(rgdal)
library(ggplot2)
library(ggmap)
# Read point data (EPSG: 4326)
sk <- st_read("points.shp")
# Read country border polygon (EPSG: 4326)
blogr4326 <- readOGR(<path>, <layer name>)
bl4326_df <- fortify(blogr4326)
# Austria box (extent)
# Longitude: 9.6 to 16.94504
# Latitude: 46.52694 to 48.81667
map <- get_map(c(left = +9.6, bottom = 46.52694, right = +16.90, top = 48.99), color = "color", crop = FALSE)
hm_sk <- ggmap(map, extent = "panel", maprange=FALSE, darken=0.0) +
geom_point(data = sk, aes(x=X_WGS84, y=Y_WGS84)) +
stat_density2d(data = sk, aes(x=X_WGS84, y=Y_WGS84, fill = ..density.., alpha=cut(..density..,breaks=c(-Inf,0.08,Inf))), contour = FALSE, bins=16, geom = 'raster', n=500) +
ggtitle("Schwarzkiefer 2016/2020") + xlab("X_WGS84") + ylab("X_WGS84") +
scale_fill_distiller(palette= "Spectral", direction=-1, limits = c(0.08, 8.50)) +
scale_alpha_manual(values=c(0,0.7), guide="none") +
geom_polygon(data=bl4326_df, aes(long, lat, group=group), color='black', fill='NA', inherit.aes = TRUE) +
coord_fixed(1.5)
hm_sk
I found out that the shift is caused by the fact that the map in the background is in the projection EPSG:3857 and my shapefiles are in the projection EPSG:4326, as explained in this post. So I projected my shapefiles to EPSG 3857 and inserted the provided code into my code, as you can see here (V2):
library(sf)
library(rgdal)
library(ggplot2)
library(ggmap)
# Read point data (EPSG: 3857)
sk <- st_read("points.shp")
# Read country border polygon (EPSG: 3857)
blogr3857 <- readOGR(<path>, <layer name>)
bl3857_df <- fortify(blogr3857)
# Austria box (extent)
# Longitude: 9.6 to 16.94504
# Latitude: 46.52694 to 48.81667
map <- get_map(c(left = +9.6, bottom = 46.52694, right = +16.90, top = 48.99), color = "color", crop = FALSE)
#-------------------------------------------------------------------------------------------------
# Following code according to this link to avoid the shift between map and country border polygon:
# https://stackoverflow.com/questions/47749078/how-to-put-a-geom-sf-produced-map-on-top-of-a-ggmap-produced-raster
# Define a function to fix the bbox to be in EPSG:3857
ggmap_bbox <- function(map) {
if (!inherits(map, "ggmap")) stop("map must be a ggmap object")
# Extract the bounding box (in lat/lon) from the ggmap to a numeric vector,
# and set the names to what sf::st_bbox expects:
map_bbox <- setNames(unlist(attr(map, "bb")),
c("ymin", "xmin", "ymax", "xmax"))
# Convert the bbox to an sf polygon, transform it to 3857,
# and convert back to a bbox (convoluted, but it works)
bbox_3857 <- st_bbox(st_transform(st_as_sfc(st_bbox(map_bbox, crs = 4326)), 3857))
# Overwrite the bbox of the ggmap object with the transformed coordinates
attr(map, "bb")$ll.lat <- bbox_3857["ymin"]
attr(map, "bb")$ll.lon <- bbox_3857["xmin"]
attr(map, "bb")$ur.lat <- bbox_3857["ymax"]
attr(map, "bb")$ur.lon <- bbox_3857["xmax"]
map
}
# Use the function:
map <- ggmap_bbox(map)
#-------------------------------------------------------------------------------------------------
hm_sk <- ggmap(map,extent = "device", maprange=FALSE) +#, extent = "panel", maprange=FALSE, darken=0.0) +
coord_sf(crs = st_crs(3857)) + # f867orce the ggplot2 map to be in 3857
geom_point(data = sk, aes(x=X_PM, y=Y_PM)) +
stat_density2d(data = sk, aes(x=X_PM, y=X_PM, fill = ..density.., alpha=cut(..density..,breaks=c(-Inf,0.08,Inf))), contour = FALSE, bins=16, geom = 'raster', n=500) +
scale_fill_distiller(palette= "Spectral", direction=-1, limits = c(0.08, 8.50)) +
scale_alpha_manual(values=c(0,0.7), guide="none") +
geom_polygon(data=bl3857_df, aes(long, lat, group=group), color='black', fill='NA', inherit.aes = FALSE) +
ggtitle("Schwarzkiefer 2016/2020") + xlab("X_3857") + ylab("X_3857")
hm_sk
Now, the problem with the shift is solved, but the density plot is not visible anymore (only map, points and borders are plotted), as you can see here:
2D-Density Plot V2 - full
2D-Density Plot V2 - detail
Any suggestions, how I can produce a plot that is proper aligned AND includes the density plot? Thanks a lot in advance!
When plotting my map of NLCD tree canopy data (a raster), the map is not straight or aligned with the map border. The skew seems to occur when using the projectRaster function. Is there a way to adjust the raster to be level and even with the border? When running the code below/looking at the uploaded image, the skew that I would like to remove is the dark grey uneven border while having the tree data fill the entire frame. I have been unable to find any solutions to this, so I appreciate any advice!
Picture of skew: 1
library(sf)
#devtools::install_github("ropensci/FedData")
library(FedData)
library(ggplot2)
library(raster)
library(RColorBrewer)
ext <- extent(734666.5, 795961.6, 4017870, 4053632)
extent <- polygon_from_extent(raster::extent(ext), proj4string='+proj=utm +datum=NAD83 +zone=16N')
WMAtc <- get_nlcd(template = polygon_from_extent(ext, (proj4string = "+proj=utm +zone=16N ellps+NAD83")), year = 2016, dataset = "Tree_Canopy", label = "Can", force.redo = T)
WMAtc_projected <- projectRaster(WMAtc, crs = "+proj=utm +zone=16N +datum=NAD83")
tc_df <- as.data.frame(WMAtc_projected, xy=TRUE)
ggplot() +
geom_raster(data = tc_df, aes(x = x, y = y, fill=tc_df[,3])) +
scale_fill_gradientn(colors = brewer.pal(8, "Greens"), name = "Tree Canopy Cover")
A professor graciously helped me fix the problem. With his code you can see where the extent bounding box is in relation to the downloaded NLCD data. When projected, the NLCD data is adjusted and extended past the original extent. To fix this, you can crop the extra data and it will realign the imagery of your maps.
library(FedData)
library(ggplot2)
library(raster)
library(RColorBrewer)
library(sf)
ext <- extent(734666.5, 795961.6, 4017870, 4053632)
extent <- polygon_from_extent(raster::extent(ext), proj4string='+proj=utm +datum=NAD83 +zone=16N')
WMAtc <- get_nlcd(template = polygon_from_extent(ext, (proj4string = "+proj=utm +zone=16N ellps+NAD83")),year = 2016, dataset = "Tree_Canopy", label = "Can")
WMAtc_projected <- projectRaster(WMAtc, crs = "+proj=utm +zone=16N +datum=NAD83")
tc_df <- as.data.frame(WMAtc_projected, xy=TRUE)
ggplot() +
geom_raster(data = tc_df, aes(x = x, y = y, fill=tc_df[,3])) +
scale_fill_gradientn(colors = brewer.pal(8, "Greens"), name = "Tree Canopy Cover") +
geom_sf(data=st_as_sf(extent), fill=NA, col="red") # show desired raster extent
WMAtc_projected_cropped = crop(WMAtc_projected, extent) #crop to remove extra bits
tc_df_cropped <- as.data.frame(WMAtc_projected_cropped, xy=TRUE)
ggplot() +
geom_raster(data = tc_df_cropped, aes(x = x, y = y, fill=tc_df_cropped[,3])) +
scale_fill_gradientn(colors = brewer.pal(8, "Greens"), name = "Tree Canopy Cover") +
geom_sf(data=st_as_sf(extent), fill=NA, col="red")
What I have:
points in the arctic and antarctic
raster data from various geophysical entities in arctic and antarctic
What I want:
A map in stereographic or any other polar projection with background map or coastlines, cropped to the extent of the points. In other words: A map like above with base map of my own choice.
What I did so far:
I loaded all the data (including land surface data from naturalearthdata; see MWE), projected them into stereographic and plotted that. The result including the polygon data looks then like this:
My MWE:
library(raster)
library(sf)
library(ggplot2)
library(rgdal)
# file load ---------------------------------------------------------------
# sea ice raster data
if (!file.exists("seaiceraster.tif")) {
url = "https://seaice.uni-bremen.de/data/smos/tif/20100514_hvnorth_rfi_l1c.tif"
download.file(url, destfile = 'seaiceraster.tif')
}
si.raster = raster::raster('seaiceraster.tif')
# land surface shapefile
if (!file.exists("110m-admin-0-countries")) {
url_land = "https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/physical/ne_10m_land.zip"
download.file(url_land, destfile = "110m-admin-0-countries")
unzip("110m-admin-0-countries")
}
world_shp = rgdal::readOGR("ne_10m_land.shp")
# points
p.data = structure(
list(
Lat = c(
73.0114126168676,70.325555278764,77.467797903163,
58.6423827457304,66.3616310851294,59.2097857474643,
75.3135274436283,60.1983078512275,72.6614399747201,
61.1566678672946,73.0822309615673,55.7759666826898,
75.1651656433833,69.0130753414173,62.3288262448589
),
Lon = c(
-59.9175490701543,-80.1900239630732,-40.4609968914928,
-61.0914448815381,-60.0703668488408,-21.027205418284,
-100.200463810276,-74.861777073788,-55.1093773178206,
-29.4108649230234,-64.5878251008461,-36.5343322019187,
-31.647365623387,-67.466355105829,-64.1162329769077
)
),
row.names = c(
1911L, 592L,2110L,3552L,3426L,1524L,635L,4668L,
3945L,2848L,3609L,36L,4262L,3967L,2725L
),
class = "data.frame"
)
p = sf::st_as_sf(p.data, coords = c("Lon", "Lat"),
crs = "+init=epsg:4326")
# project -----------------------------------------------------------------
polar.crs = CRS("+init=epsg:3995")
si.raster.proj = projectRaster(si.raster, crs = polar.crs)
world_shp.proj = sp::spTransform(world_shp, polar.crs)
p.proj = sf::st_transform(p, polar.crs)
# preparation -------------------------------------------------------------
AG = ggplot2::fortify(world_shp.proj)
# make raster to data.frame
si.raster.df = si.raster.proj %>%
raster::crop(., p.proj) %>%
raster::rasterToPoints(., spatial = TRUE) %>%
as.data.frame(.)
colnames(si.raster.df) = c("val", "x", "y")
# plot --------------------------------------------------------------------
ggplot() +
# geom_polygon(data = AG, aes(long, lat, group = group)) + # un-comment to see
geom_raster(data = si.raster.df, aes(x = x, y = y, fill = val)) +
geom_sf(data = p.proj, color = "green", size = 3)
I've changed the workflow in your example a bit to add the stars package for the sea ice data, but I think it should get you what you're looking for. You'll need to adjust the crop size to expand it a little, as the points p are right on the edge of the plotted area. st_buffer might help with that.
I used the crs from the seaicebuffer.tif file for all of the objects.
The .tif file has a crs that I'm not able to easily transform on my computer. It seems to be able to use meters as a lengthunit and might be a polar stereographic (variant B) projection. The points & world data don't seem to have a problem transforming to it though, which is why I've used it throughout.
library(raster)
library(sf)
library(ggplot2)
library(rgdal)
library(stars)
si <- stars::read_stars('seaiceraster.tif')
world_sf = rgdal::readOGR("ne_10m_land.shp") %>%
st_as_sf() %>%
st_transform(st_crs(si))
# p <- ... same as example and then:
p <- st_transform(p, st_crs(si))
# get a bounding box for the points to crop si & world.
p_bbox <- st_bbox(p) %>%
st_as_sfc() %>%
st_as_sf() %>%
st_buffer(100000)
# crop si & world_sf to an area around the points (p)
world_cropped <- st_crop(world_sf, p_bbox)
si_cropped <- st_crop(si, p_bbox)
#Plot
ggplot() +
geom_sf(data = world_cropped,
color = 'black',
fill = 'NA',
size = .2) +
geom_stars(data = si_cropped) +
geom_sf(data = p, color = 'red') +
scale_fill_continuous(na.value = 0)
Ugly hack for the southern .tif that stars reads as factors:
si <- stars::read_stars('20150324_hvsouth_rfi_l1c.tif', NA_value = 0 )
si$"20150324_hvsouth_rfi_l1c.tif" <- as.numeric(si$"20150324_hvsouth_rfi_l1c.tif")
ggplot() + geom_stars(data = si)
I'm trying to limit a map plot to a specific area. coord_map is preferred to scale_x_continuous and y equivalent, since the latter mess up the polygons. But here I'm finding it fails for some reason. Here's my code (downloads a 57kb shapefile):
require(maptools)
require(ggplot2)
download.file('https://dl.dropboxusercontent.com/u/46043231/UK.zip', "uk.zip", method="internal", mode="wb")
unzip('uk.zip')
uk = readShapePoly('uk_outline_1000m.shp')
print(bbox(uk))
min max
x 259.9625 655566.4
y 7211.7025 1218558.9
uk2 = fortify(uk)
(p = ggplot(uk2, aes(x=long, y=lat, group=group)) + geom_polygon() + coord_equal())
But when coord_map is used the plot disappears:
p + coord_map(xlim=c(0, 630000), ylim=c(0, 1000000))
Any idea what's going on??
I would try something like this to test a few options.
library(maptools)
library(ggplot2)
library(rgdal)
library(raster)
library(latticeExtra)
Download and read the data
download.file('https://dl.dropboxusercontent.com/u/46043231/UK.zip',
"uk.zip", method="internal", mode="wb")
unzip('uk.zip')
uk <- readOGR(dsn = getwd(), layer = 'uk_outline_1000m')
Data is assumed to use OSGB 1936 / British National Grid.
More about at SpatialReference
proj4string(uk) <- CRS('+init=epsg:27700') # EPSG 27700
extent(uk)
bb.uk <- as(extent(uk), 'SpatialPolygons') # a spatial object
proj4string(bb.uk) <- CRS('+init=epsg:27700')
Write projected shapefile of uk bbox. I'll write it out to map layers with QGIS. It will be my reference system.
writeOGR(as(bb.uk, 'SpatialPolygonsDataFrame'),
dsn = getwd(),
layer = 'bbuk2_bng', driver = 'ESRI Shapefile')
The desired bounding box. Using projected coordinates
bb.uk2 <- as(extent(c(0, 630000), c(0, 1000000)), 'SpatialPolygons')
proj4string(bb.uk2) <- CRS('+init=epsg:27700')
Write projected shapefile of user bbox
writeOGR(as(bb.uk2, 'SpatialPolygonsDataFrame'),
dsn = getwd(),
layer = 'bbuk2user_bng', driver = 'ESRI Shapefile')
QGis map using British National Grid EPSG:27700
Plot projected layers
Base plot
plot(uk, col = 'grey50', axes = T, xlim=c(-50000, 705566.4),
ylim=c(-50000, 1325000))
plot(bb.uk, add = T)
plot(bb.uk2, border = 'red', add = T)
spplot
I took a arbitrary window to expand plot area.
sp::spplot(uk, zcol = 'NAME_ISO', scales = list(draw = TRUE),
xlim=c(-50000, 705566.4), ylim=c(-50000, 1325000),
col.regions="grey90") +
latticeExtra::layer(sp.polygons(bb.uk, fill = NA, col = 'blue')) +
latticeExtra::layer(sp.polygons(bb.uk2, fill = NA, col = 'red'))
ggmap with projected layers
uk.df = fortify(uk) # admin
bbuk.df <- fortify(bb.uk) # country bbox extent
bbuk2.df <- fortify(bb.uk2) # user bbox extent
plot it
p <- ggplot() + geom_polygon(data = uk.df, aes(x=long, y=lat, group=group)) +
geom_polygon(data = bbuk.df, aes(x=long, y=lat, group=group),
colour = 'blue', fill = NA) +
geom_polygon(data = bbuk2.df, aes(x=long, y=lat, group=group),
colour = 'red', fill = NA) +
coord_equal() # cartesian
p
plot it with user bounding box
p + coord_equal(xlim=c(0, 630000), ylim=c(0, 1000000))
Now ggplot with geographic (unprojected) coordinates
WGS84 Unprojected Coordinate Reference System
p.wgs84 <- CRS("+init=epsg:4326") # WGS84 Long Lat
Convert projected layer to WGS84
uk.wgs89 <- spTransform(uk, p.wgs84)
Geographic bbox uk
bbuk.wgs84 <- as(as(extent(uk.wgs89), 'SpatialPolygons'),
'SpatialPolygonsDataFrame')
Geographic bbox of user extent
bbuk2.wgs84 <- spTransform(bb.uk2, p.wgs84)
bbuk2.wgs84 <- as(bbuk2.wgs84, 'SpatialPolygonsDataFrame')
Plot it with ggplot and cartesian map
uk.df = fortify(uk.wgs89) # admin
bbuk.df <- fortify(bbuk.wgs84) # country bbox extent
bbuk2.df <- fortify(bbuk2.wgs84) # user bbox extent
The result is not what I'd expect. I don't figure out why the red box is distorted.