Transversing the Mercatorverse

If you know me, or you’ve even briefly glanced at the About section of this site, you’ll know I currently work in location data intelligence. A fairly important part of that is understanding global addressing data, and one aspect of that is geocoordinates.

Now, to most people, geocoordinates = latitude & longitude and, frankly, that’s fine. Some days, I wish that’s all it meant to me, too. But it doesn’t. There’s more. In fact, more than even I knew…

So, it turns out that there are over 6,000 coordinate reference systems in use across the world. But, luckily, there are only a few with “global adoption”. WGS84 is one of those, which gives you coordinates such as 40.7128° N, 74.0060°, which I’m sure you’ll recognise.

But again, there are dozens of others and sometimes, it’s really useful to be able to convert between them.

Enter GeoCrsTransform. Catchy, eh?

Why?

If you’ve ever tried to convert coordinates between different reference systems (think WGS84 to OSGB36), you’ll know it’s a bit like translating between Klingon and Elvish. There are standards, but they’re arcane, and the tools are either overkill or… not quite right. So, I built GeoCrsTransform—a .NET library that makes CRS transformations simple, testable, and extensible.

What Does It Do?

GeoCrsTransform lets you:

  • Transform coordinates between geodetic and projected CRSs (e.g., WGS84 ↔ OSGB36)
  • Handle datum shifts, ellipsoids, and projections
  • Plug in your own CRS catalog if you’re feeling fancy (there’s a handy json file with all the existing definitions for reference)

Getting Started

First, add the library to your project (assuming you’ve got the source or a NuGet package):

<ItemGroup>
  <ProjectReference Include="../src/GeoCrsTransform/GeoCrsTransform.csproj" />
</ItemGroup>

If you’d like to just jump in, there’s a sample API project attached to this blog post.

Basic Usage

Let’s say you want to convert a latitude/longitude from WGS84 to eastings/northings:

using GeoCrsTransform;

var transformer = CoordinateTransform.CreateManaged();
var latlong= new GeoCoordinate(51.5074, -0.1278, 0);
var northings= CrsId.Parse("EPSG:4326");

var result = transformer.Transform(latlong, wgs84, northings);
var projected = (ProjectedCoordinate)result.Output;

You can also go the other way, or use custom CRS definitions if you’re working with something exotic.

Under the Hood

The library is built around a few core types:

  • GeoCoordinate (latitude/longitude)
  • ProjectedCoordinate (easting/northing)
  • CrsId (identifies the CRS, e.g., “WGS84”)
  • CoordinateTransformer (the brains of the operation)

It’s all test-driven, with a json based catalog you can extend or swap out.

Everything is better with an API

Well, everything is even more better with ice cream (that’s grammatically incorrect, I know), but that won’t help us here, so there’s a minimal ASP.NET Core project that exposes CRS transformation as a web service. It’s attached to this blog post, so feel free to grab a copy.

Endpoints

  • POST /transform — Transform coordinates between CRSs
  • GET /crs — List supported CRSs

Example: Transforming Coordinates

Request:

POST /transform
{
  "lat": 51.5074,
  "lon": -0.1278,
  "from": "WGS84",
  "to": "OSGB36"
}

Response:

{
  "easting": 530000,
  "northing": 180000,
  "crs": "OSGB36"
}

Example: Listing CRSs

Request:

GET /crs

Response:

[
  { "id": "WGS84", "name": "World Geodetic System 1984" },
  { "id": "OSGB36", "name": "Ordnance Survey Great Britain 1936" }
]

Try It Out

You can grab the library via nuget:

dotnet add package GeoCrsTransform

Or you can check it out on Github.

Alternatively, you can grab the sample project below, run it and head to /swagger for interactive docs and testing. You can poke at the endpoints, see example requests, and have more fun than you ever thought possible where geocoordinates were involved. Maybe.

Just grab, unzip and go:

dotnet run --project GeoCrsTransform.MinimalApiSample

I promise, this is almost over

I know this is quite a dry topic, but as I dug into it further, it did actually become more interesting (where’s that “nerd” gif..?). The complexity of the maths behind it is, to my weird brain, fascinating. So, if you do have a need to convert coordinates (why wouldn’t you?), this library is designed to be simple, extensible, and easy to drop into your .NET projects. If you use it, I’d love to hear your feedback.