++ed by:

2 PAUSE users

Toby Thurston


plot_maps - make a nice index sheet for a map series

This programme shows off several features of Geo::Coordinates::OSGB. If you have a working TeXLive installation with GhostScript installed, you can use it to produce PDF index maps of the various map series provided by Geo::Coordinates::OSGB::Maps.


  perl plot_maps.pl --series A --paper A3 --outfile some.pdf 
                    --[no]grid --[no]graticule --[no]towns 
                    --[no]ostn --[no]coast


--series [ABC...]

Print the outlines of one of more map series. The argument should be one of the keys of the map series defined by Geo::Coordinates::OSGB::Maps. Currently: A=Landranger, B=Explorer, C=One-inch, H=Harvey Mountain Maps, J=Harvey Superwalker.

You can combine keys to get a concordance but the result may not be easy to read.

Default is none - no map outlines are printed.

--paper A[01234]

The preferred paper size for the output. Default is A3.

--outfile some.pdf

The output file name. Default depends on the choice of --series. With no series selected the name will be National_grid.pdf. Otherwise it will be Index_for_map_series_X.pdf where X is the chosen series.


Show the grid lines and squares. Turn off with --nogrid. Default is on.


Show lines of latitude and longitude. Turn off with --nograt. Default on.


Show a few major cities in the background. Turn off with --notowns.


Show the boundaries of the OSTN02 transformation dataset. Default is off.


Plot the coast line found in gb-coastline.shapes. This input is an ESRI shape dump file with longitude and latitude pairs on each line, and each shape separated by a line with a leading # character. The code below shows you how to read it and convert it to grid coordinates. Default is to show the coast lines. Turn off with --nocoast.

--usage, help, man

Show increasing amounts of help text, and exit.


Print version and exit.


This section describes how Geo::Coordinates::OSGB functions are used.

Converting longitude and latitude to grid

Since the output consists of the whole country formatted for an A4 or A3 page a thin line on the page will represent a distance of at least 500 m on the ground so the ll_to_grid_helmert routine gives all the accuracy we need.

The coast line shapes also include points outside the OSTN02 area; this is another reason to stick to ll_to_grid_helmert directly.

Shape files usually have the coordinates given with longitude before latitude; be sure to swap them round for ll_to_grid_helmert.

Getting the scale right

The usual grid area is 700km by 1250km, but to allow for some room round the map the scale is worked out by allowing for 1000km to be printed horizontally across the page. For A3 the page width is 297mm, so the scale is 297 mm : 1000 km or about 1:3,360,000, but in the current example the units of measure are PostScript points so the width of the page is 842 pt and the scale factor is 1000000/842 = 1188.

If you don't care about the page size, it's convenient to use a scale factor of 1000 and represent 1km on the ground by 1 PostScript point. This is a scale of about 1:2,835,000. If you are printing small areas you might like to use the conventional scales favoured by the OS:

   Scale                Factor to use
   1:250,000            88.194
   1:50,000             17.6388
   1:25,000              8.8194

Once you have set your scale, you can apply it by passing the output from ll_to_grid through ... map { $_/$scale } ... .

Working with the map data

The implementation of Geo::Coordinates::OSGB::Maps is experimental and may change significantly in future releases. Possibly the hash exports will be replaced by a more sophisticated object-oriented interface. In the mean while, this programme shows how to use the current map data.

To plot a map, it's best to join up the points returned by $maps{$k}->{polygon} rather than make any assumption about the size of the sheets. This is because most of the sheets are not regular rectangles. The polygon data includes all the marginal extensions as well as insets. To find the centre of the map, the simple approach is to find the average of the lower left and upper right corners given in $maps{$k}->{bbox}. This is OK for most sheets, but not so good for the odd shaped insets.

You can distinguish an inset from a main sheet with the {parent} key. If $k is one of the keys from %maps then $maps{$k} is an inset if $k ne $maps{$k}->{parent}. The parent key links to the parent sheet for the inset.


If you get the options wrong or you supply any arguments you will get the usage message.

Otherwise you'll get a short pause while we create a Metapost file.

When that's done, we try to run mpost. If you don't have Metapost installed you will get an OS error and the programme will die with the message "Metapost call failed".

If Metapost runs ok, then we try to run epstopdf to turn the PostScript output produced by Metapost into a PDF. If this doesn't work, the programme will die with the message "epstopdf call failed".

If everything works ok, then the programme tries to clean up the temporary files that Metapost will have created. If this does not work you will get a message saying "Failed to delete temporary file:...".

Finally if all has worked, you will get a message telling you that the programme has created a PDF file.


You need a working copy of mpost and epstopdf to get the PDF output. The simplest way to install them is to install a complete TeXLive distribution, including GhostScript. This is easy on OSX or Linux. On Windows these functions are also provided by MikTeX.


Toby Thurston -- 30 Jul 2017