Last active
January 1, 2017 10:53
-
-
Save valentinitnelav/b4d76cd9e84414ac4d1ac48d64615784 to your computer and use it in GitHub Desktop.
Shift central/prime meridian by splitting the world map in two
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# =================================================================================== | |
# Shift central/prime meridian and plot world map with ggplot | |
# =================================================================================== | |
# __________ Load needed libraries __________ # | |
library(data.table) | |
library(ggplot2) | |
library(rgdal) | |
library(rgeos) | |
library(maps) | |
library(maptools) | |
# __________ Get world map in proper format __________ # | |
# Load world map as map object | |
worldmap <- map("world", fill=TRUE, plot=FALSE) | |
# Convert map object to SpatialPolygons object (check ?map2SpatialPolygons) | |
WGS84 <- CRS("+proj=longlat +datum=WGS84") | |
worldmapPolys <- map2SpatialPolygons(worldmap, | |
IDs=sapply(strsplit(worldmap$names, ":"), "[", 1L), | |
proj4string=WGS84) | |
# __________ Split world map by "split line" __________ # | |
# check "split polygon by line" at: | |
# https://stat.ethz.ch/pipermail/r-sig-geo/2015-July/023168.html | |
# shift central/prime meridian towards west – positive values only | |
shift <- 180+20 | |
# create "split line" to split worldmap | |
split.line = SpatialLines(list(Lines(list(Line(cbind(180-shift,c(-90,90)))), ID="line")), | |
proj4string=WGS84) | |
# gBuffer solution to avoid 'TopologyException' when intersecting line with world polys | |
# http://gis.stackexchange.com/questions/163445/r-solution-for-topologyexception-input-geom-1-is-invalid-self-intersection-er | |
worldmapPolys <- gBuffer(worldmapPolys, byid=TRUE, width=0) | |
# intersecting line with world polys | |
line.gInt <- gIntersection(split.line, worldmapPolys) | |
# create a very thin polygon (buffer) out of the intersecting "split line" | |
bf <- gBuffer(line.gInt, byid=TRUE, width=0.000001) | |
# split world polys using intersecting thin polygon (buffer) | |
worldmapPolys.split <- gDifference(worldmapPolys, bf, byid=TRUE) | |
# plot(worldmapPolys.split) # check map | |
# __________ Prepare data for ggplot and shift coordinates __________ # | |
# transform map in a data table that ggplot can use | |
XY <- data.table(map_data(as(worldmapPolys.split, "SpatialPolygonsDataFrame"))) | |
# Shift coordinates (data.table way) | |
XY[, long.new := long + shift] | |
XY[, long.new := ifelse(long.new > 180, long.new-360, long.new)] | |
# plot shifted map | |
ggplot() + | |
geom_polygon(data=XY, | |
aes(x=long.new, y=lat, group=group), | |
colour="black", | |
fill="gray80", | |
size = 0.25) + | |
coord_equal() | |
# __________ Additional example with projected coordinates __________ # | |
# example with Robinson projection | |
PROJ <- "+proj=robin +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs" | |
# assign matrix of projected coordinates as two columns in data table | |
XY[, c("X","Y") := data.table(project(cbind(long.new, lat), proj=PROJ))] | |
# plot shifted world map | |
ggplot() + | |
geom_polygon(data=XY, | |
aes(x=X, y=Y, group=group), | |
colour="black", | |
fill="gray80", | |
size = 0.25) + | |
coord_equal() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment