6 April 2010

Reading and Geocoding Ordinance Survey’s open data in .NET

Ordinance Survey’s recent OpenData initiative has made a huge amount of UK location-based data freely available for download – a real gift for those of us who are working with mapping applications.

All the data is available on a new license that allows you to copy, distribute and adapt the data. There really is a wealth of goodies in here:

  • OS Locator contains coordinates for every street in the UK
  • Code-Point Open is a data set that shows the location of every UK postcode
  • Political boundaries including local authorities, counties and parliamentary seats are defined by Boundary-Line
  • Road, rail and river infrastructure is outlined in a vector format by Meridian 2.

The only drawback is that the data isn’t available in formats that are familiar to C# developers. A fair amount of work can be required to get the data into a usable format.

Getting longitude and latitude from OS map co-ordinates

Most developers will be used to working with latitude and longitude coordinates. This is the ETRS89 standard, which is based on the World Geodetic System of coordinate-based geography. Ordinance Survey, on the other hand, uses its own grid-based national reference system – the OSGB36 standard.

Converting coordinates between these two standards is not straightforward – as with any location-based data, the maths can get frighteningly complex if you want fully accurate results. There are a number of libraries that claim to do the conversion,but the results can often be an approximation at best.

The best solution is the Grid InQuest library, a free-to-use COM library built in C++ that was commissioned by Ordinance Survey themselves. It does make for very accurate conversions but, being a COM library, it’s slightly cantankerous to use.

Once installed, you can use the library in a .NET project by adding a reference to the COM library GIQ60Lib. Before you do any conversions you will have to initialise the library with a few lines of code which are shown below.

public static GIQ60Lib.OSTransformationClass InitialiseConverter()
{
    //* Create the converter
    GIQ60Lib.OSTransformationClass converter = new OSTransformationClass();

    //* Get the data file path
    string dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
    dir = System.IO.Path.Combine(dir, "GridInQuest"); 

    //* Set the data file path
    if (converter.SetDataFilesPath(dir) != eErrorCode.eSuccess)
    {
        throw new FileNotFoundException("Could not find Grid InQuest data file.");
    }
    //* Set the area to Great Britain
    if (converter.SetArea(eArea.eAreaGreatBritain) != eErrorCode.eSuccess)
    {
        throw new InvalidOperationException("Failed to set Grid InQuest area to Great Britain.");
    }
    //* Initialise
    if (converter.Initialise("GIQ.6.0") != eErrorCode.eSuccess)
    {
        throw new InvalidOperationException("Failed to initialize Grid InQuest.");
    }

    return converter;
}

Once your converter has been initialised you can use it to read in Ordinance Survey grid values and convert them to longitude and latitude values:

//* Get the converter (cached in the real world, obv)
GIQ60Lib.OSTransformationClass converter = InitialiseConverter();
eVertDatum output;
//* Set the OSGB36 value to convert
eErrorCode result = converter.SetOSGB36(inputX, inputY, inputHeight, out output);
//* Fetch the corresponding ETRS89 geocode
result = converter.GetETRS89Geodetic(out outputLatitude, out outputLongitude, out outputHeight);

Reading ESRI Shapefile data for polygons and lines

Another challenge can be the file formats themselves. Point-based data comes in handy CSV files, but any shape-based data uses the ESRI Shapefile format. This is a (more-or-less) open specification for representing geographic data that is based on a collection of files – one of which is in dBase IV format.

There are no native libraries in .NET for reading Shapefile data and the specification is quite complex. Unless you want to roll up your sleeves and start reading bytes according to a detailed data format then you should consider reaching for one of the many .NET-based Shapefile readers that are available.

Rob Ellison’s ESRI Shapefile Reader on CodePlex is a nice open-source C# project that worked out of the box for me. There are other options though, including ESRI’s own developer components and the wealth of components available on the open source GIS website are also worth a look.

Filed under C#, Net Framework.