I want to show how big Brazilian Amazon Forest is, plotting different countries inside it. Like in this image:
To accomplish that, I loaded some shapefiles and changed their projection to one that would keep the areas proportional, like Cylindrical Equal Area:
library(rgdal)
countries <- readOGR("shp","TM_WORLD_BORDERS-0.3")
countries <- spTransform(countries,CRS("+proj=cea"))
amzLegal <- readOGR("shp","amazlegal")
amzLegal@proj4string <- CRS("+proj=longlat")
amzLegal <- spTransform(amzLegal,CRS("+proj=cea"))
plot(amzLegal)
FR <- countries[which(countries$NAME == "France"),]
for (i in 1:length(FR@polygons[[1]]@Polygons)) {
FR@polygons[[1]]@Polygons[[i]]@coords[,1] = FR@polygons[[1]]@Polygons[[i]]@coords[,1]-7180000
FR@polygons[[1]]@Polygons[[i]]@coords[,2] = FR@polygons[[1]]@Polygons[[i]]@coords[,2]-4930000
}
plot(FR,col="blue",add=T)
I'm getting this (without the lines, which I added later):
According to Google Earth, the red line is about 950 km (in France), the same measure of the black line (in Brazil). So of course the Cylindrical Equal Area is not the proper projection to use, since it enlarges the longitude and shrinks the latitude. What projection should I use, then? One that keeps shape AND size? I have also tried the Lambert Azimuthal Equal Area, but didn't work either. I like the Goode's Homolosine but it's not really a single projection, but a mix of different techniques. Here is a list of the possible projections: http://www.remotesensing.org/geotiff/proj_list/
EDIT: Following @CiaPan answer, I came to this function:
translate <- function(obj,x,y,ang=0,adiciona=T) {
maxLat <- -90
for (i in 1:length(obj@polygons[[1]]@Polygons)) {
for (j in 1:nrow(obj@polygons[[1]]@Polygons[[i]]@coords)) {
lat <- obj@polygons[[1]]@Polygons[[i]]@coords[j,2]
if (lat > maxLat) {
maxLat <- lat
maxLon <- obj@polygons[[1]]@Polygons[[i]]@coords[j,1]
}
}
}
lon0 <- maxLon*pi/180
lat0 <- maxLat*pi/180
y <- y*pi/180 # degrees to radians
ang <- ang*pi/180
x1 = 180
x2 = -180
y1 = 90
y2 = -90
for (i in 1:length(obj@polygons[[1]]@Polygons)) {
for (j in 1:nrow(obj@polygons[[1]]@Polygons[[i]]@coords)) {
lon <- obj@polygons[[1]]@Polygons[[i]]@coords[j,1]*pi/180 - lon0 #1 V to Greenwich
lat <- obj@polygons[[1]]@Polygons[[i]]@coords[j,2]*pi/180
X <- cos(lon)*cos(lat) #2 Cartesian coords
Y <- sin(lon)*cos(lat)
Z <- sin(lat)
X0 <- X
X <- X0*cos(lat0) - Z*sin(-lat0) #3 V to Equator
Z <- X0*sin(-lat0) + Z*cos(lat0)
Y0 <- Y
Y <- Y0*cos(ang) - Z*sin(ang) #4 rotate by ang
Z <- Y0*sin(ang) + Z*cos(ang)
X0 <- X
X <- X0*cos(y) - Z*sin(y) #5 V to y
Z <- X0*sin(y) + Z*cos(y)
lat <- asin(Z) #6
lon <- asin(Y/cos(lat))*180/pi + x
lat <- lat*180/pi
if (lon < x1) { x1 <- lon } #bbox
if (lon > x2) { x2 <- lon }
if (lat < y1) { y1 <- lat }
if (lat > y2) { y2 <- lat }
obj@polygons[[1]]@Polygons[[i]]@coords[j,1] <- lon
obj@polygons[[1]]@Polygons[[i]]@coords[j,2] <- lat
}
}
obj@bbox[1,1] <- x1
obj@bbox[1,2] <- x2
obj@bbox[2,1] <- y1
obj@bbox[2,2] <- y2
plot(obj,col="red",border="black",add=adiciona)
}
Where obj is a spatialPolygons object, x and y are long and lat of destination. The function translates and plot the object. Usage can be:
library(rgdal)
par(mar=c(0,0,0,0))
countries <- readOGR("shp","TM_WORLD_BORDERS-0.3",encoding="UTF-8")
plot(countries,col=rgb(1,0.8,0.4))
translate(countries[which(countries$NAME == "France"),],-60,0,0,T)
where the shapefile was downloaded from here. Thank you all!