Converting old Ordnance Survey Height Data

I’m currently putting together some pages for the Maptitude How-To pages covering Maptitude’s support for digital terrain models and elevation models. Left over from my undergraduate geology days, I happened to have the Ordnance Survey 1:50,000 height data files for the 20km SH64 square (my dissertation covered an area straddling the SH75SW and SH75SE 5km squares). These files were old, dating from 1993 and used the Ordnance Survey’s “First Generation” NTF data format. Although Maptitude advertises some NTF support, even these files were early by NTF standards. I also suspect Maptitude only knows about conventional cartographic NTF files and not the contour or DEM files that I had.

Therefore the only solution was to write a program to convert the data into a more usable format.

Maptitude can create terrain models from any point dataset, so all we need to do is to convert the file into a format that Maptitude can read as point data. A simple CSV (comma separated value) file that provides eastings, northings, and height is sufficient. eastings and northings refer to Ordnance Survey Grid Reference coordinates. These are easy to extract from the NTF file. Conversion to longitude,latitude coordinates would be more involved, and unnecessary.

If I was approaching this problem afresh, I would probably choose Python. It is great for scripting these data conversion utilities. However I already had some early 1990s C routines which extracted data from the NTF DEM file. These did things like produce DXF grids (for AutoCAD) and produce empty cross-sectional templates (for geological cross-sections). I dusted these off, and boy was that C code long in the tooth! The adapted utility is as follows:

Convert a 20km OSGB NTF DEM file to CSV format

     creategrid origX origY input.NTF output.csv

Output: CSV with OSGridX, OSGridY, height
(C) Copyright 2015 Winwaed Software Technology LLC

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int	main (int argc, char *argv[]);
void	process_height(char *height);
void	read_line(char *line);

int		x,y;
FILE		*fntf,*fdxf;
int		*heights[401];

void	read_line(char *line)
	line[0] = '\0';
	while (!feof(fntf) && strlen(line) < 3)

int	main (int argc, char *argv[])
  char	data[128],height[5];            
  int	i,j,fx,fy;
  int   origX, origY;
  char	finput[50],foutput[50];

  printf("Create a CSV grid from a 20km sq Ordnance Survey NTF DTM\n");

  if (argc <5)
      printf("not enough input parameters\n");
      return 0;

  origX = atoi(argv[1]);
  origY = atoi(argv[2]);
  strcpy(foutput, argv[4]);

  printf("Input File: %s\n", finput);
  printf("Output File: %s\n", foutput);
  printf("Input file's local origin: %d,%d\n", origX, origY);

  if ((fntf = fopen(finput,"r")) == NULL)
  {	printf("Cannot open input file!\n");
	return 0;

  printf("\nReading input file...\n");
  x = -1;
  y = 0;
  for (i=0; i<401; i++)
    heights[i] = malloc(401*sizeof(int));
  while (!feof(fntf))
  {	read_line(data);
	if (atoi(data) == 51)
		for (i = 0; i < 21; i++)
			for (j = 0; j < 19; j++)
				height[4] = '\0';
				heights[x][y++] = atoi(height);
		for (j = 0; j < 2; j++)
		    	height[4] = '\0';
       			heights[x][y++] = atoi(height);
  // file has been successfully read

  // open the output file
  if ((fdxf=fopen(foutput,"wt"))==NULL)
  {	printf("Cannot open output file!");
	return 0;

  printf("\nWriting CSV File...\n");

  // loop over points
  for (fx=0; fx<401; fx++)
	int xp = origX + fx * 50;
	for (fy=0; fy<401; fy++)
		int yp = origY + fy * 50;				
		float h = (float)( heights[fx][fy] );
		fprintf(fdxf, "%06d, %06d, %.1f\n", xp,yp, h );

  // Close file
  printf("File completed!\n");
  return 0;

Note the horrible use of global variables. These were in the original scripts, and it was easier to keep them, than to completely re-write the input code.

The new script now be used from the command line. Example usage:

./creategrid 260000 340000 VOL16001.NTF sh64_output.csv

The first two values are the national eastings and northings origin of theNTF file, specified in metres. The SH 100km square corresponds to 200000,300000; so SH64 corresponds to 260000,340000.

Next is the input DEM NTF file. We ignore the corresponding contour files. The final parameter is the name of the output CSV file, which is overwritten.

The resulting CSV file is then easily read into Maptitude. Here it is plotted as a terrain surface (elevation: green to orange) with the Maptitude Streets layer visible:

DEM imported into Maptitude

DEM loaded into Maptitude. Plotted with orange for high elevation. Major roads are the orange or cyan lines in the valley bottoms. View is towards the southwest, up the Lledr Valley. Note the A470 running up the valley and through the Crimea Pass to Blaenau Ffestiniog.

Leave a Reply