Using GDAL >= 1.10.0 compiled with SQLite and SpatiaLite:
ogr2ogr world_shifted.shp world.shp -dialect sqlite -sql "SELECT ShiftCoords(geometry,180,0) FROM world"
or:
ogr2ogr -s_srs EPSG:4326 -t_srs "+proj=longlat +ellps=WGS84 +pm=-180 +datum=WGS84 +no_defs" world_shifted.shp world.shp
Both commands produce a longitude offset of 180°, i.e. a prime meridian of -180° is considered. In fact:
>ogrinfo world_shifted.shp world_shifted | grep Extent
Extent: (0.000000, -90.000000) - (360.000000, 83.623596)
The difference between the two commands is that with a longitude offset (2nd try) data are simply reprojected using -180° as prime meridian, while shifting the coordinates geometries (1st try) are altered, even if the result is apparently the same.
EDIT
If there are parts in 0-180 that should not move, it's possible to adapt this working solution: https://gis.stackexchange.com/a/73164/22405
Clip the two parts:
ogr2ogr world_part1.shp world.shp -clipsrc -180 -90 0 90
ogr2ogr world_part2.shp world.shp -clipsrc 0 -90 180 90
Shift only the first part:
ogr2ogr world_part1_shifted.shp world_part1.shp -dialect sqlite -sql "SELECT ShiftCoords(geometry,360,0), CNTRY_NAME FROM world_part1"
Then, merge the second part and the first shifted:
ogr2ogr world_0_360_raw.shp world_part2.shp
ogr2ogr -update -append world_0_360_raw.shp world_part1_shifted.shp -nln world_0_360_raw
Finally, dissolve countries boundaries of world_0_360_raw.shp
obtaining world_0_360.shp
by country names. For instance:
ogr2ogr world_0_360.shp world_0_360_raw.shp -dialect sqlite -sql "SELECT ST_Union(Geometry), CNTRY_NAME FROM world_0_360_raw GROUP BY CNTRY_NAME"
Google Maps, like most web maps, works in WGS84, Web Mercator (Auxiliary Sphere) - EPSG 3857.
http://spatialreference.org/ref/sr-org/epsg3857-wgs84-web-mercator-auxiliary-sphere/
Planar units are meters.
Also, see this similar question.
PROJCS["WGS 84 / Pseudo-Mercator",
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,
AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0,
AUTHORITY["EPSG","8901"]],
UNIT["degree",0.0174532925199433,
AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4326"]],
PROJECTION["Mercator_1SP"],
PARAMETER["central_meridian",0],
PARAMETER["scale_factor",1],
PARAMETER["false_easting",0],
PARAMETER["false_northing",0],
UNIT["metre",1,
AUTHORITY["EPSG","9001"]],
AXIS["X",EAST],
AXIS["Y",NORTH],
EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"],
AUTHORITY["EPSG","3857"]]
Best Answer
+180 and -180 are the same meridian on the Earth, so they are essentially the same value when defining extents. And as you demonstrated, defining extents with the same value will produce zero width extents.
This is why one of the +-180 values must be exclusive and one must be inclusive.
edit: Technically, there isn't a reason why they couldn't have +180 and -180 both be valid, but when creating an API, less is more. It's better to restrict input up front, rather than having to deal with multiple cases for the same value in your code.
This is somewhat similar to using One's Complement to store signed integer values. Having to test for two different representations of zero is a pain, so this is one of the reasons why Two's Complement is much more popular.