What does this package do for me?

mapscanner is an R package that enables lines drawn by hand on maps to be converted to spatial objects. The package has two primary functions: one for producing maps, and one for rectifying hand-drawn lines to the coordinate system of the original map. The package is intended for use in social surveys and similar endeavours in which hand-drawn markings on maps need to be converted to spatial objects. Maps can be either paper- or screen-based. Markings on paper maps need to be scanned, photographed, or otherwise digitised, while maps with screen-based markings need to be saved as .png- or .pdf-format images.

How do I use it?

The package is designed to enable the following workflow:

  1. Generate a map with the ms_generate_map() function, which automatically produces both .pdf and .png versions;

  2. Either print the .pdf version to use as desired in any kind of survey environment, or use either the .pdf or .png versions in digital form for screen-based surveys.

  3. Draw on the map;

  4. For paper maps, digitise the drawn-on (from here on, “modified”) map, converting it to either .pdf or .png format; and

  5. Rectify the modified version against the original via the ms_rectify_map() function, which distinguishes individual annotations, and converts each one to a spatial object able to be analysed in any desired manner.

Practical tips

The mapscanner package is intended to aid a practical workflow, and so a few practical tips may be recommended here to ensure best results:

  1. The original digital files generated with ms_generate_map() are necessary to rectify subsequently drawn-on and scanned maps, and so must be retained at all times.
  2. Marks drawn on maps should be coloured – any black or grey markings will be ignored. This has the advantage that individual annotations not intended to be converted to spatial objects (such as unique identification or participant codes) may be made on maps in black or grey.
  3. For drawings of areas, best results will be achieved through ensuring that all lines form closed polygons. While the default type = "hulls" argument should work even when lines are not closed, the type = "polygons" argument will generally produce more accurate results, yet should only be used when all lines form closed polygons (see below for details on how these two differ).
  4. Digitised versions of paper maps should contain white borders, so do not, for example, photograph modified maps lying on dark surfaces. If maps are to be photographed, then best results can be achieved by simply placing them on a larger, enclosing sheet of white paper.

The following two sections describe the two primary functions of the mapscanner package, corresponding to the two primary steps of producing maps to be used in surveys (or other activities), and rectifying modified maps against these originals in order to extract spatial objects. The second of these sections also describes the kinds of markings able to be recognised, and the kinds of spatial objects to which these may be converted.

Mapbox API tokens

Map generation with mapscanner requires a personal token or key from mapbox, which can be obtained by following the links from https://docs.mapbox.com/api/. If you already have a token, the easiest way to use it with mapscanner is to create (or edit) a file ~/.Renviron, and insert a line,


This will then be available every time you start R, without any need to explicitly set the token each time you want to use the package. The token may be given any unique name that includes “mapbox” (case insensitive). Alternatively, if you wish to keep your token truly private, and only use it for your current R session, you may load mapscanner, and then run set_mapbox_token(<my_mapbox_token>).

Map generation

Having obtained and set a mapbox token as described above, the ms_generate_map() function can be used to generate printable maps for a specified bounding box in both .pdf and .png formats. Usage is a simple as,

ms_generate_map ("chennai india", mapname = "chennai")
## Successfully generated 'chennai.pdf' and 'chennai.png'

The two generated maps are saved in the current working directory (getwd()). To save maps in alternative locations, the mapname parameter can optionally specify paths. To provide finer control over the scales of maps, precise bounding boxes can also be submitted. To determine desired bounding boxes, we recommend using the ‘openstreetmap.org’ website, zooming to a desired area, then clicking the “Export” button. A window will appear which includes the bounding coordinates of the current screen. Even finer control can be gained by clicking beneath this coordinate window on the line which says, “Manually select a different area,” which brings a drag-able rectangle onto the current screen. The coordinates in the bounding box then simply need to be entered in to the bbox parameter of ms_generate_map() in the order (xmin, ymin, xmax, ymax) – or anti-clockwise from the left-hand coordinate.

The amount of detail in resultant maps is controlled by the max_tiles argument, with larger values producing more detail, and resulting in larger file sizes. The default value of max_tiles = 16L (where the L symbol tells Rto treat the value as an integer) should produce acceptable results for maps extending across hundreds of metres to a few kilometres. Smaller-scale maps may require higher values, and vice-versa. Map generation is relatively fast, and so different values can be readily trialled.

Maps are generated in two formats, because the .pdf version will generally be the most convenient for printing, while the png version should be retained as the “master” copy against which to rectify subsequently scanned-in version. Behind the scenes, the function downloads a series of vector map tiles from mapbox, and converts them to a rasterBrick object from the raster package. This rasterBrick object is invisibly returned from the function:

x <- ms_generate_map ("chennai india", mapname = "chennai")
## Successfully generated 'chennai.pdf' and 'chennai.png'
## class      : RasterBrick
## dimensions : 1147, 562, 644614, 3  (nrow, ncol, ncell, nlayers)
## resolution : 38.21851, 38.21851  (x, y)
## extent     : 8921157, 8942635, 1442787, 1486624  (xmin, xmax, ymin, ymax)
## crs        : +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
## source     : memory
## names      : index_1.1, index_1.2, index_1.3
## min values :       107,       107,       107
## max values :       254,       254,       254

This rasterBrick object contains raster information for the three colour channels of the image, and so may also be used for immediate viewing within R with raster::plotRGB(x).

Standard uses of the package should not need to explicitly access or modify these data, but it is nevertheless possible to do so, and then use a custom-modified object to produce the external .pdf and .png files by submitting the rasterBrick object to ms_generate_map():

ms_generate_map (raster_brick = x, mapname = "chennai")

Map rectification

Having produced digital maps using the ms_generate_map() function as described above, and having printed, variously drawn-on, and, for paper maps, scanned the result back in to digital form, the package can then be used to rectify the hand-drawn markings against the original map with the ms_rectify_map() function, which returns the drawn-on objects as spatial objects in Simple Features (sf) format. The only requirement is that the drawn-on objects are coloured; black or grey objects will be ignored. As described above, this has the advantage that maps may be annotated in ways not intended to be converted to spatial objects (such as adding unique identification or participant codes), through simply providing such annotations in grey or black.

The ms_rectify_map() function has two primary arguments, specifying the names (and locations) of the original and modified map files – in that order: ms_rectify_map(original, modified). These files should ideally be in .png formats, but will be auto-converted from .pdf if needed. The package comes with two sample maps, both in .png format. The first is the reference version needed for rectification, while the second has two red lines drawn upon it: