Rmap - a package for geographic maps in R.

Barry Rowlingson January 2003

The Rmap library is intended to be a framework for geographic map plotting in R. It is designed to operate with map projections and multiple data formats.

Map projections are handled using the PROJ4 library.

Current supported data formats are:

In development:
  • S-style 'maps' derived from .gon, .line, and .N files

    Installation

    Source Code/Unix version (tested on Linux)

    Get the Rmap_1.1.0.tar.gz file. Extract it to a temporary directory with tar zxvf Rmap_1.1.0.tar.gz - you can install R packages straight from tar files but you may need to edit some things at this stage of the package's development.

    Projections

    If you want to use map projections, get and install the PROJ4 library. Make sure you build and install a shared library (libproj.so or similar). If this is not in a system directory such as /usr/local/lib/ then you need to edit the Makevars file in the Rmap/src directory before installing Rmap.

    If you dont want Projection support, edit Makevars and remove -lproj from the PKG_LIBS line. Actually, no, that wont work because the PROJ4 library symbols will be undefined and the code wont load. Get and install PROJ4 - its worth it. Again, make sure you build a shared PROJ4 library, so that you have libproj.so in a system directory.

    If you really cant get PROJ4 built, then I think if you delete the projectit.c file from the src directory, and remove -lproj from Makevars then you will build without PROJ4 support.

    Shapefile Support

    For ESRI shapefiles you must first get and install the SHAPELIB library. You can either get it from the Shapelib page or get it as part of the Gdal library. The Gdal version has some bugs fixed that are present in the standalone version (as of v1.2.9) and the CVS version has even more fixed. Getting the CVS version is an exercise for the reader.

    Make sure you build and install a shared library, libshp.so or similar). If this is not in a system directory such as /usr/local/lib then you need to edit the file Makevars before building and installing Rmap. Make sure the path to the shapelib header file is specified too.

    OGR library support

    Get and install the GDAL library from www.remotesensing.org and build a shared library with OGR support. If you cant get this, then edit the Makevars file and remove OGR support.

    Installing R Library

    From the directory above the temp directory, do: R CMD INSTALL Rmap or to install to a non-system directory, do: R CMD INSTALL -l ~/MyRLibs/ Rmap - in the latter case you need to do: library(Rmap,lib.loc="~/MyRLibs") to access it.

    Windows Version

    There is no Windows binary version at the moment. If you get the source code version and install it without support for the external libraries (shapefile, ogr, proj4) then you can use Rmap with native R map objects only. Until we get these libraries compiled under Windows this will be the case. If you can compile these libraries under Windows then great, please let me know, and I'll have a go linking it all with Rmap.

    There is some code for reading Shapefiles that uses only R code for reading binary files, and since this needs no shapefile library it should work under Windows. If anyone wants to port this into Rmap then please do!

    Usage

    The Rmap library uses objects in R to access general geographical data sources. These data sources could be simple R objects, objects that access data files, or potentially objects that get their data from databases or servers.

    As an example, we illustrate how to draw maps using an ESRI shapefile. This is a relatively simple data format, and widely used. Physically a shapefile consists of three actual system files:

    Logically it can be thought of much like an R data frame, with each row also having an associated shape. This shape could be a point, line, or polygon entity.

    This gives us our basic model for geographic data - a data frame with associated spatial objects. Many operations on data frames can also be used on geographic objects in Rmap.

    Creation and simple usage

    For a concrete example, consider the shapefile euadmll.shp (it is fairly conventional to consider the .shp file and call it 'the shapefile' even though a .shx and .dbf file are also involved). This is a map of regions in a large part of western Europe (obtained from the UNEP web site as an E00 file and converted to a shapefile using e002shp).

    We create a new object with the shapefile function:

    > euadmll <- shapefile("euadmll.shp")
    Warning message: 
    Invalid names in DBF file, new names are:
     EUADMLL# is now EUADMLL.
    EUADMLL-ID is now EUADMLL.ID 
    
    First note that some of the names in the DBF file were not good expressions for R column names, and so were renamed. We can check this with the names() function:
    > names(euadmll)
     [1] "AREA"       "PERIMETER"  "EUADMLL."   "EUADMLL.ID" "ARRGCD"    
     [6] "NURGCD"     "ARRGCTCD"   "ARRGLBLV"   "TOTAREA"    "POP80"     
    [11] "POP85"      "POP87"      "POP88"      "POP89"      "POP90"     
    [16] "POP91"     
    
    If we print this object out we get a message:
    > euadmll
    its a shapefile
    the file is /home/rowlings/Geog/Shapelib/Rshape/inst/samples/euadmll.shp
    its dimension is  2556  rows by  16  columns
    
    We can access data using $NAME as with a data frame:
    > euadmll$AREA[25:28]
    [1]  0.012 21.600  0.210  0.024
    
    Note that the precision of the result is limited to whatever precision was specified in the DBF file when it was created.

    Subscripting

    You can select rows and columns from one of these objects. However the shapefile and DBF file are never altered. All that happens is that the selection is tracked so that only selected rows or columns are visible.
    > euadmll[1:10,]
    its a shapefile
    the file is /home/rowlings/Geog/Shapelib/Rshape/inst/samples/euadmll.shp
    its dimension is  10  rows by  16  columns
    
    If you want to get the data itself, then convert the object to a data frame:
    > as.data.frame(euadmll[5:10,1:5])
       AREA PERIMETER EUADMLL# EUADMLL-ID ARRGCD
    1 0.201     7.162        5          6   NO03
    2 0.087      1.55        6          7   NO03
    3 0.003     0.261        7          5   NO03
    4 0.138      3.51        8          8   NO03
    5 0.057     1.828        9         10   NO03
    6 0.006     0.387       10         11   NO16
    

    Basic Mapping

    You can plot a map of your object, or a subset of it, using the plot() function:
    > plot(euadmll)
    > plot(euadmll[grep("^UK",euadmll$ARRGCD),])
    
    By default this will use the most appropriate type of map according to the data set - such as points, lines or polygons. You can get the type with the maptype(euadmll) function.

    You can also use points(), lines() and polys() functions to add to an existing plot.

    Map Projections

    Any of the functions that draw maps based on latitude-longitude can also be given a proj= function to apply a map projection. The argument is a character string that is passed to the PROJ4 library - see the documentation for PROJ4 for full details - here is an example of a plot using a Mercator projection:
    > plot(euadmll,proj="+proj=merc")
    
    Once a plot has been started using a projection, further plots should use the same projection parameter.

    The underlying function for projecting coordinates is project(xy,proj,inv=F) where xy is a 2-column matrix of coordinates and proj is a string for the PROJ4 library. The inv parameter controls whether the forward or inverse transform is used. Passing inv=T causes the inverse transform to be used (if available for that projection) so that coordinates on the plot device can be converted back to latitude-longitude values.

    Data format specifics

    Further information on specific data formats is available:

    Adding a New Data Format

    To Be Done...

    Bugs

    Plenty. Expect crashes. Do save.image() early and often.

    Filled polygons

    I dont think R can properly draw polygons with holes, so I've bodged something that seems to work but can draw stray thin lines on some graphics devices.

    Lines across map edges

    If you try and draw a map of the world such that polygons wrap from east to west, say, the polygons will be drawn incorrectly.

    Projections off the globe

    Some projections return +/- Inf values, and this mucks up the setting of the extent. Probably need to modify project() to return NA and make sure the extent calculation doesnt return Infs when stuff is projected to all NAs.